Stagger

Introduce list items at short intervals to communicate order and rhythm.

Preview

Live preview

Animate several items one after another with a small delay between each, creating a cascade.

Preview
  1. Item 1
  2. Item 2
  3. Item 3
  4. Item 4
Authoritative vocabulary

Definition and close-term distinctions

English definitions are preserved verbatim from Animation Vocabulary; translations and distinctions help you choose precisely.

Canonical termstagger

Stagger

交错动画
Authoritative definition

Animate several items one after another with a small delay between each, creating a cascade.

Chinese translation

让多个项目依次播放动画,并在相邻项目之间加入短延迟,形成级联节奏。

Browse all 91 terms
Design contract

Decide before this motion ships

Purpose, frequency, trigger, timing, interruptibility, and gesture rules shape the implementation.

Purpose

Introduce grouped items at short intervals to communicate order, grouping, and rhythm.

Frequency

Use for a list's low-frequency first appearance; shorten or remove staggering for continuously updating lists.

Trigger

Trigger when the group is ready or its container enters view, following reading order.

Enter / exit

Stagger entrances in order; usually fade exits together and reverse-stagger only when hierarchy benefits.

Interruptibility

On data changes, animate only added or moved items while existing items keep their position.

Gesture and keyboard

Make items operable as soon as they appear, and keep keyboard order aligned with the DOM.

Reduced-motion strategy

Remove inter-item delay and show the group immediately or with one short shared fade.

Output

Copy into your interface

Current parameters update visual-state CSS, semantic HTML, the required vanilla JS runtime, and an interaction prompt.

Updates with parameters
motion.css
.motion-demo.motion-demo--stagger {
  position: relative;
  display: grid;
  place-items: center;
  width: min(100%, 34rem);
  min-height: 15rem;
  padding: 2rem;
  overflow: hidden;
  color: #18181b;
  background: #fafafa;
  border: 1px solid #e4e4e7;
  border-radius: 12px;
  isolation: isolate;
}

.motion-demo.motion-demo--stagger *, .motion-demo.motion-demo--stagger *::before, .motion-demo.motion-demo--stagger *::after {
  box-sizing: border-box;
}

.motion-demo.motion-demo--stagger .motion-surface {
  position: relative;
  display: grid;
  gap: 0.65rem;
  width: min(100%, 18rem);
  padding: 1.25rem;
  background: #ffffff;
  border: 1px solid #e4e4e7;
  border-radius: 8px;
  box-shadow: 0 1px 2px rgb(0 0 0 / 6%), 0 10px 28px rgb(0 0 0 / 7%);
}

.motion-demo.motion-demo--stagger .motion-line {
  display: block;
  width: 100%;
  height: 0.5rem;
  background: #e4e4e7;
  border-radius: 999px;
}

.motion-demo.motion-demo--stagger .motion-line:last-child { width: 62%; }

.motion-demo.motion-demo--stagger .motion-button {
  position: relative;
  min-height: 2.75rem;
  padding: 0.75rem 1.1rem;
  color: white;
  font: inherit;
  font-weight: 700;
  background: #18181b;
  border: 0;
  border-radius: 7px;
  cursor: pointer;
}

.motion-demo.motion-demo--stagger .motion-button:focus-visible { outline: 3px solid rgb(37 99 235 / 32%); outline-offset: 3px; }

.motion-demo.motion-demo--stagger .motion-action-row {
  display: flex;
  justify-content: center;
  gap: 0.5rem;
  margin-top: 0.85rem;
}

.motion-demo.motion-demo--stagger .motion-replay-scene {
  width: min(100%, 22rem);
  display: grid;
  place-items: center;
}

.motion-demo.motion-demo--stagger .motion-pausable-scene {
  width: min(100%, 22rem);
  display: grid;
  place-items: center;
}

.motion-demo.motion-demo--stagger button.motion-surface {
  color: inherit;
  font: inherit;
  text-align: start;
  cursor: pointer;
}

.motion-demo.motion-demo--stagger .motion-replay-button,
.motion-demo.motion-demo--stagger .motion-undo-button,
.motion-demo.motion-demo--stagger .motion-dismiss-button,
.motion-demo.motion-demo--stagger .motion-pause-button {
  min-height: 2.75rem;
  padding: 0.65rem 0.9rem;
  color: #18181b;
  font: 650 0.78rem/1 ui-sans-serif, system-ui, sans-serif;
  background: #ffffff;
  border: 1px solid #d4d4d8;
  border-radius: 7px;
  cursor: pointer;
}

.motion-demo.motion-demo--stagger .motion-replay-button:focus-visible,
.motion-demo.motion-demo--stagger .motion-undo-button:focus-visible,
.motion-demo.motion-demo--stagger .motion-dismiss-button:focus-visible,
.motion-demo.motion-demo--stagger .motion-pause-button:focus-visible,
.motion-demo.motion-demo--stagger [data-reorder-item]:focus-visible,
.motion-demo.motion-demo--stagger [data-swipe-target]:focus-visible {
  outline: 3px solid rgb(37 99 235 / 32%);
  outline-offset: 3px;
}

.motion-demo.motion-demo--stagger .motion-status {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.motion-demo.motion-demo--stagger .motion-ripple-ink {
  position: absolute;
  width: 12px;
  height: 12px;
  pointer-events: none;
  background: rgb(255 255 255 / 72%);
  border-radius: 50%;
  transform: translate(-50%, -50%) scale(0.95);
  opacity: 0;
}

.motion-demo.motion-demo--stagger .motion-state-stack { position: relative; width: min(100%, 18rem); height: 9rem; }
.motion-demo.motion-demo--stagger .motion-state { position: absolute; inset: 0; display: grid; place-items: center; padding: 1rem; background: #ffffff; border: 1px solid #e4e4e7; border-radius: 8px; }
.motion-demo.motion-demo--stagger .motion-state--to { background: #18181b; color: white; }

.motion-demo.motion-demo--stagger .motion-scroll-track > span { color: #71717a; font: 600 0.72rem/1.2 ui-monospace, monospace; letter-spacing: 0.08em; text-transform: uppercase; }
.motion-demo.motion-demo--stagger .motion-orbit-item { display: grid; place-items: center; width: 2.5rem; height: 2.5rem; color: white; background: #2563eb; border-radius: 50%; }
.motion-demo.motion-demo--stagger .motion-text-stack { position: relative; width: min(100%, 18rem); min-height: 4rem; }
.motion-demo.motion-demo--stagger svg { width: min(100%, 20rem); height: auto; }

.motion-demo.motion-demo--stagger .motion-list { display: grid; gap: 0.6rem; width: min(100%, 18rem); margin: 0; padding: 0; list-style: none; }
.motion-demo.motion-demo--stagger .motion-list-item { padding: 0.8rem 1rem; background: #ffffff; border: 1px solid #e4e4e7; border-radius: 8px; animation: motion-stagger 220ms cubic-bezier(0.23, 1, 0.32, 1) both; }
.motion-demo.motion-demo--stagger .motion-list-item:nth-child(2) { animation-delay: 50ms; }
.motion-demo.motion-demo--stagger .motion-list-item:nth-child(3) { animation-delay: 100ms; }
.motion-demo.motion-demo--stagger .motion-list-item:nth-child(4) { animation-delay: 150ms; }
.motion-demo.motion-demo--stagger .motion-list-item:nth-child(5) { animation-delay: 200ms; }
.motion-demo.motion-demo--stagger .motion-list-item:nth-child(6) { animation-delay: 250ms; }
.motion-demo.motion-demo--stagger .motion-list-item:nth-child(7) { animation-delay: 300ms; }
.motion-demo.motion-demo--stagger .motion-list-item:nth-child(8) { animation-delay: 350ms; }
@keyframes motion-stagger { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: none; } }

@keyframes motion-stagger-reduced-fade {
  from { opacity: 0.84; }
  to { opacity: 1; }
}

.force-reduced-motion .motion-demo.motion-demo--stagger {
  animation: motion-stagger-reduced-fade 160ms cubic-bezier(0.23, 1, 0.32, 1) both !important;
}

.force-reduced-motion .motion-demo.motion-demo--stagger *,
.force-reduced-motion .motion-demo.motion-demo--stagger *::before,
.force-reduced-motion .motion-demo.motion-demo--stagger *::after {
  animation: none !important;
  animation-delay: 0ms !important;
  animation-iteration-count: 1 !important;
  transition-property: opacity, color, background-color, border-color !important;
  transition-duration: 160ms !important;
  transition-delay: 0ms !important;
  scroll-behavior: auto !important;
}

.force-reduced-motion .motion-demo.motion-demo--stagger .motion-button,
.force-reduced-motion .motion-demo.motion-demo--stagger [data-reorder-item],
.force-reduced-motion .motion-demo.motion-demo--stagger [data-swipe-target],
.force-reduced-motion .motion-demo.motion-demo--stagger [data-spring-target] {
  transform: none !important;
}

.force-reduced-motion .motion-demo.motion-demo--stagger .motion-path { stroke-dashoffset: 0 !important; }
.force-reduced-motion .motion-demo.motion-demo--stagger .motion-word--from { opacity: 0 !important; visibility: hidden; }
.force-reduced-motion .motion-demo.motion-demo--stagger .motion-word:not(.motion-word--from) { opacity: 1 !important; filter: none !important; transform: none !important; }

@media (prefers-reduced-motion: reduce) {
  .motion-demo.motion-demo--stagger {
    animation: motion-stagger-reduced-fade 160ms cubic-bezier(0.23, 1, 0.32, 1) both !important;
  }

  .motion-demo.motion-demo--stagger *, .motion-demo.motion-demo--stagger *::before, .motion-demo.motion-demo--stagger *::after {
    animation: none !important;
    animation-delay: 0ms !important;
    animation-iteration-count: 1 !important;
    transition-property: opacity, color, background-color, border-color !important;
    transition-duration: 160ms !important;
    transition-delay: 0ms !important;
    scroll-behavior: auto !important;
  }

  .motion-demo.motion-demo--stagger .motion-button,
  .motion-demo.motion-demo--stagger [data-reorder-item],
  .motion-demo.motion-demo--stagger [data-swipe-target],
  .motion-demo.motion-demo--stagger [data-spring-target] {
    transform: none !important;
  }

  .motion-demo.motion-demo--stagger .motion-path { stroke-dashoffset: 0 !important; }
  .motion-demo.motion-demo--stagger .motion-word--from { opacity: 0 !important; visibility: hidden; }
  .motion-demo.motion-demo--stagger .motion-word:not(.motion-word--from) { opacity: 1 !important; filter: none !important; transform: none !important; }
}
Review notes

Pre-delivery review

  • Include the final item's delay in the total-duration review.
  • For long lists, animate only the initially visible items.
Accessibility

Keep information accessible

Reduced motion

Remove inter-item delay and show the group immediately or with one short shared fade.

Parameters

Parameter reference

ParameterRange / optionsDefaultPurpose
duration80ms–1200ms220msControls the time required for one motion cycle.
stagger20ms–120ms50msAdjusts stagger.
count2–84Adjusts item count.
distance0px–120px18pxControls how far the element travels.
easeSoft / Snap / Calm / LinearSoftControls how velocity changes over time.