Stagger

스태거

Animating a group of elements with a small delay between each, instead of all at once — so a list or grid ripples in instead of popping in as a block.

Also known as: Staggered animationSequential delay
···
html
<div class="grid" id="grid"></div>
css
.grid{display:grid;grid-template-columns:repeat(3,1fr);gap:10%;width:60%;aspect-ratio:1}
.grid i{border-radius:8px;background:var(--accent);opacity:0;transform:translateY(60%);
  animation:pop 2.4s calc(var(--i) * 90ms) infinite}
@keyframes pop{
  0%{opacity:0;transform:translateY(60%)}
  14%{opacity:1;transform:translateY(0)}
  70%{opacity:1;transform:translateY(0)}
  85%{opacity:0;transform:translateY(-30%)}
  100%{opacity:0;transform:translateY(60%)}
}
js
const grid = document.getElementById('grid');
for (let i = 0; i < 9; i++) {
  const d = document.createElement('i');
  d.style.setProperty('--i', String(i));
  grid.appendChild(d);
}

Give each element's animation-delay (or transition-delay) as its index times a fixed interval. Too large a gap feels sluggish; too small and you can't tell it's staggered at all. 30–80ms is a common range.

It's common on card grids, notification lists, and onboarding checklists — it signals "these belong to one group" while softening the feeling of the whole screen changing at once.

CSS's animation-delay only applies to the first play, but if each element's value differs, that phase offset carries through every subsequent loop — which is why the stagger keeps repeating even on an infinite animation.

When to use

Works well for 6–12 items. Beyond that the total delay grows too long — shrink the interval or skip staggering.