RSS FeedTwitterMastodonBlueskyShare IconHeart IconGithub IconArrow IconClock IconGUI Challenges IconHome IconNote IconBlog IconCSS IconJS IconHTML IconShows IconOpen Source Software IconSpeaking IconTools IconShuffle IconNext IconPrevious IconCalendar IconCalendar Edit IconNotebook IconObservable Notebooks IconSlash IconGoogle G Icon
ul > li {
  --stagger: calc((sibling-index() - 1) * .1s);

  transition:
    opacity   1s var(--ease-3)        var(--stagger),
    translate 1s var(--ease-spring-3) var(--stagger);
}
My google avatar.3 min read

Let the stagger experiments begin

css

2019, I proposed an idea to help remove a ton of boilerplate code from CSS and HTML while also making stagger effects easier on authors. The proposal ended up being sibling-index() and sibling-count().

Fun news! You can try it in Canary today and I've got this little example to help kick off some ideas for you!

Try on Codepen

Staggering animation #

Instead of inlining a CSS variable for each element:

<div class="parent" style="--sibling-count: 5">
  <div style="--sibling-index: 1"></div>
  <div style="--sibling-index: 2"></div>
  <div style="--sibling-index: 3"></div>
  <div style="--sibling-index: 4"></div>
  <div style="--sibling-index: 5"></div>
</div>

You can use sibling-index() to retrieve it just in time instead of doing the work in the template or JS.

Clean that HTML up to make room for sibling-index() by removing all the inline styles:

<div class="parent">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>

and then drop in this new magic bomb:

.parent > * {
  transition: opacity 0.3s ease;
  transition-delay: calc(sibling-index() * 100ms);
}

and now you have a 100ms staggered crossfade transition effect 🤓

Staggering color #

There's nothing stopping you from using sibling-index() to stagger a color change, or anything else!

Here the hue increments by 50 each element.

.parent > * {
  --hue: calc(sibling-index() * 50);
  color: oklch(70% 70% var(--hue));
}

You could easily add a min() or clamp() or trig functions to help you too.

Time to experiment #

Share with me what you build! Fork this Codepen

14 mentions #

200likes
36reposts
  • Josh W. Comeau
  • Bill Criswell
  • James Nash
  • Stephen Fluin
  • Wil van der Tuin
  • GENKI
  • Sue
  • Sara Soueidan
  • Álvaro Montoro
  • Shaw
  • Iron
  • Hyeseong Kim
  • Toby Evans
  • Stefan Matei
  • Roni Laukkarinen
  • Jason Lengstorf
  • Heather Buchel
  • Agustín Díaz
  • Thomas Broyer
  • Owen Blacker
  • Christian de Botton
  • Krzysztof Hankiewicz (he/him)
  • caryfook
  • Povilas
  • Vincent De Oliveira
  • Emmie Päivärinta
  • Harry Llewelyn
  • ????️ Jim Schofield ????
  • Kevin Lee Drum
  • alex
  • Marcos de Miguel
  • blokche
  • Gustav Hansen
  • Fynn Ellie Becker
  • Katherine Kato

Join the conversation on

Niiiiiiiiiice. That's exciting.
Bill CriswellBill Criswell
This is very cool
Frank KorfFrank Korf
Woah CSS just keeps getting huge win after win ???????????????????????? Nicely staggered list animations without a library! ????
Peter Cruckshank (he/him)Peter Cruckshank (he/him)
Hell yeah
Andy StewartAndy Stewart
That looks so smooth!
Ryan BurgessRyan Burgess
I didn’t know this was coming! This is awesome! ????
Nils RiedemannNils Riedemann
With this we can finally do boustrophedon (snake layout) without any JS! codepen.io/Link2Twenty/...
Andrew BoneAndrew Bone
Pleas tell me there's no js in this. I'm tired of making everything that needs an animation a client component ????
Jomo KigoJomo Kigo
I feel like I'll use these two a *lot* in coming experiments. So convenient! codepen.io/nocksock/pen...
Nils RiedemannNils Riedemann
Getting some sass blasts from the past.
Ivan ČurićIvan Čurić
holy shit I just remembered doing clamp lerping a decade ago. The sourcemaps are still up! ????
Ivan ČurićIvan Čurić
ngl I often think that clamp is lerp and then I’m sad it isn’t.
Nils RiedemannNils Riedemann
I think I found a bug. Chrome breaks if you use either one inside tan(). codepen.io/0xfabio/pen/... Check comment on css line 50.
Fabio GiolitoFabio Giolito