staggerStagger
交错动画Animate several items one after another with a small delay between each, creating a cascade.
让多个项目依次播放动画,并在相邻项目之间加入短延迟,形成级联节奏。
Introduce list items at short intervals to communicate order and rhythm.
Animate several items one after another with a small delay between each, creating a cascade.
English definitions are preserved verbatim from Animation Vocabulary; translations and distinctions help you choose precisely.
staggerAnimate several items one after another with a small delay between each, creating a cascade.
让多个项目依次播放动画,并在相邻项目之间加入短延迟,形成级联节奏。
Purpose, frequency, trigger, timing, interruptibility, and gesture rules shape the implementation.
Introduce grouped items at short intervals to communicate order, grouping, and rhythm.
Use for a list's low-frequency first appearance; shorten or remove staggering for continuously updating lists.
Trigger when the group is ready or its container enters view, following reading order.
Stagger entrances in order; usually fade exits together and reverse-stagger only when hierarchy benefits.
On data changes, animate only added or moved items while existing items keep their position.
Make items operable as soon as they appear, and keep keyboard order aligned with the DOM.
Remove inter-item delay and show the group immediately or with one short shared fade.
Current parameters update visual-state CSS, semantic HTML, the required vanilla JS runtime, and an interaction prompt.
.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; }
}Remove inter-item delay and show the group immediately or with one short shared fade.
| Parameter | Range / options | Default | Purpose |
|---|---|---|---|
duration | 80ms–1200ms | 220ms | Controls the time required for one motion cycle. |
stagger | 20ms–120ms | 50ms | Adjusts stagger. |
count | 2–8 | 4 | Adjusts item count. |
distance | 0px–120px | 18px | Controls how far the element travels. |
ease | Soft / Snap / Calm / Linear | Soft | Controls how velocity changes over time. |