Jordan Smalls

Software Engineer

Stagger a list entrance with vanilla CSS

Fade and slide list items into view, with a 0.05-second stagger.

Give each item a zero-based index. The CSS uses that number to delay each row by another 0.05 seconds. Add more items by continuing the index.

html
<ul class="staggered-list">
  <li style="--index: 0">First item</li>
  <li style="--index: 1">Second item</li>
  <li style="--index: 2">Third item</li>
</ul>

@starting-style defines the initial appearance when an item first renders. Each row fades in and moves up 6px over 250ms. The normal styles keep the content visible in browsers that do not support @starting-style. This is an entrance transition, not a scroll-triggered animation.

css
.staggered-list > li {
  opacity: 1;
  transform: translateY(0);
  transition-property: opacity, transform;
  transition-duration: 250ms;
  transition-timing-function: cubic-bezier(0.23, 1, 0.32, 1);
  transition-delay: calc(var(--index, 0) * 0.05s);
}

@starting-style {
  .staggered-list > li {
    opacity: 0;
    transform: translateY(6px);
  }
}

/* Show focused items immediately. */
.staggered-list > li:focus-within {
  transition: none;
}

@media (prefers-reduced-motion: reduce) {
  .staggered-list > li {
    transition: none;
  }
}