Staggered reveals: choreography, not decoration
Fade in twelve cards simultaneously and the user perceives one event: “content appeared.” Fade them in 40 milliseconds apart and something different happens—the eye is led across the grid, item by item, in the order you chose. Same elements, same duration, completely different comprehension.
Stagger is information. It communicates sequence, grouping, and priority before a single word is read.
The index variable pattern
/* Each item knows its position */
<li style="--i: 0"></li>
<li style="--i: 1"></li>
li {
animation: reveal .5s cubic-bezier(.2,.8,.2,1) both;
animation-delay: calc(var(--i) * 40ms);
}The numbers that matter: 30–60ms between items. Under 30ms the stagger blurs back into a blob; over 80ms the tail of a long list feels broken. And cap the total: for big grids, use min(var(--i) * 40ms, 400ms) so item forty does not arrive a second and a half late.
“A stagger is a sentence. Each element is a word, and the delay is the space between them.”
Direction carries meaning
Stagger top-to-bottom for reading order, from the trigger outward for cause-and-effect (a filter click rippling through results), and reverse it on exit—last in, first out feels physically right. Keep individual durations identical; vary only the delays. When elements both start late and move slowly, the choreography collapses into mush.
Pair the pattern with animation-timeline: view() and the stagger rides the scroll instead of the clock—items introducing themselves as they arrive. Decoration fades; choreography explains.