tm-stagger sequences its direct children. It needs no classes on the
children themselves.
The vocabulary
State-triggered replay
A container carryingdata-state plays the entrance when open and the exit when
closed:
animation-name is what re-triggers a keyframe animation, so toggling
the attribute replays the choreography in the new direction with no JavaScript
and no key-remounting trick.
A container with no state attribute keeps the pre-0.8 behaviour exactly: its
children enter once, on mount.
Reverse without reordering
tm-stagger-from-end reads a second generated index counted from the last
child. Nothing moves in the DOM.
flex-direction: row-reverse, order, or a negative
delay — three tricks that all break keyboard navigation or screen-reader order
to buy a visual effect.
Combine
tm-stagger-exit (or a closed data-state) with tm-stagger-from-end
to get the shape most people want: the list arrives top-down and leaves
bottom-up, as if it were being folded away.Nesting
A nestedtm-stagger sequences its own children from its own delay. It does not
continue the outer count, and its step does not leak back out.
--tm-stagger-index on itself, so a nested scope can never
inherit its parent’s position. To make the two read as one continuous sequence,
offset the inner group with tm-delay-*.
The generated-child limit
Indices are generated for the first 20 children. Child 21 onward reuses the last index. That means a long list lands together at the end rather than all starting at the front — the failure mode is “the tail arrives as a group”, not “the tail jumps ahead of the head”.With the default 100ms step a 20-item sequence already runs for 1.9 seconds. Past
that, a stagger stops reading as choreography and starts reading as a loading
bar. If you have 200 rows, you want a single entrance on the container, not a
stagger.
MAX_STAGGER_CHILDREN in scripts/build.mjs if you are
building the stylesheet yourself.
When a stagger is the wrong answer
Stagger reads as hierarchy when the siblings are semantic — title, then description, then actions — and as a queue when it is a list of equivalent rows.Tuning
Reduced motion
Every child collapses to a 1ms animation with no delay, so the list appears at once, fully legible. The container is named explicitly in the reduced-motion rule because it animates children that carry notm- class of their own.