Staggered CSS Animations with sibling-index()
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.
/* Manual index per nth-child */li:nth-child(1) { --i: 0;}li:nth-child(2) { --i: 1;}li:nth-child(3) { --i: 2;}li:nth-child(4) { --i: 3;}/* … repeat for every item … */li { transition-delay: calc(0.1s * var(--i));}li { transition: opacity .25s ease, translate .25s ease; transition-delay: calc(0.1s * (sibling-index() - 1));}sibling count Browser Support
Since 2026 this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.
Works in all modern browsers. May need a fallback for older browsers.
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.