Staggered animations without nth-child hacks
Staggered list animations used to require manually setting --index on each :nth-child or counting in JavaScript. The sibling-index() function gives every element automatic awareness of its position.
2li:nth-child(1) { --i: 0; }
3li:nth-child(2) { --i: 1; }
4li:nth-child(3) { --i: 2; }
5li:nth-child(4) { --i: 3; }
6/* … repeat for every item … */
7
8li {
9 transition-delay: calc(0.1s * var(--i));
10}
2 transition: opacity .25s ease, translate .25s ease;
3 transition-delay:
4 calc(0.1s * (sibling-index() - 1));
5}
Automatic indexing
sibling-index() returns each element's 1-based position. No manual counting, no matter how many items.
Dynamic safe
Add or remove items and the stagger adapts automatically. The old nth-child approach breaks when the list changes.
Count siblings too
sibling-count() gives the total. Use both for radial layouts, equal distribution, and more.
How it works
The classic staggered animation technique required setting a custom property like --i on every :nth-child selector, then using calc(0.1s * var(--i)) for the delay. This was fragile: add a list item and you need another rule. Some developers set the index via inline styles or JavaScript instead, adding complexity.
The sibling-index() function returns a 1-based integer representing the element's position among its siblings. Use it directly in calc() for staggered delays, radial positioning, or any layout that depends on element order. Its companion sibling-count() returns the total number of siblings, enabling formulas like distributing items evenly around a circle.