WebCraft

sibling-index()

A stagger that survives a new item

  • first to arrive
  • then this one
  • then this one
  • and last of all

Caveatsibling-index() returns a plain number, so it has to be given a unit by hand: calc(sibling-index() * 140ms), never the bare function. It counts element siblings from one, including elements set to display: none, so a hidden row still spends its place in the sequence and leaves a gap you did not ask for.

FallbackAn unsupported function makes the whole declaration invalid, so every item falls back to the delay it would otherwise have, usually zero, and the list arrives in one go rather than in sequence. Declare a sensible animation-delay first and let the calc() override it where it parses.

HTML + CSS
<ul><li></li><li></li></ul>

li {
  animation: slide-in .5s both;
  /* one rule, any number of items */
  animation-delay:
    calc(sibling-index() * 140ms);
}

Published

Questions

<details name>

How do I stagger an animation without writing nth-child rules?

Multiply the delay by the item's own position: animation-delay: calc(sibling-index() * 140ms). One declaration covers a list of any length, where a chain of :nth-child rules has to be extended by hand every time the list grows.

Does sibling-index() count hidden elements?

Yes. It counts element siblings from one, so an element set to display: none still occupies its number and leaves a gap in the sequence. Take hidden rows out of the DOM rather than hiding them if the rhythm matters.

What happens in a browser that does not support sibling-index()?

The declaration containing it is invalid and is dropped, so the item keeps whatever delay was set before it, usually none, and the whole list animates at once. Nothing breaks visually, the sequencing is just gone.