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.

Old way12+ lines
/* 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));}
Modern
5 lines
li   {  transition: opacity .25s ease, translate .25s ease;  transition-delay:    calc(0.1s * (sibling-index() - 1));}
Newly availableSince 202670% global usage

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.

138+
154+
26.2+
138+
click to replay the staggered animation
1
2
3
4
5
6
7
8

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.

Lines Saved
12+ → 5
Scales to any list size
Old Approach
nth-child per item
Manual --index variables
Modern Approach
sibling-index()
Tree counting functions

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.

ESC