staggerStagger
交错动画English definition
Related items start at offset times, turning one transition into a readable sequence.
Chinese translation
让多个项目依次播放动画,并在相邻项目之间加入短延迟,形成级联节奏。
staggerIntroduce list items at short intervals to communicate order and rhythm.
Related items start at offset times, turning one transition into a readable sequence.
Implement Stagger: Introduce list items at short intervals to communicate order and rhythm. Use Duration 220ms, Stagger 50ms, Item count 4, Distance 18px, Easing soft. Trigger it once when state changes and keep it replayable. Use semantic HTML, scope CSS to .motion-demo--stagger. Provide equivalent low-motion behavior for prefers-reduced-motion and .force-reduced-motion.
<div class="motion-demo motion-demo--stagger" data-motion="stagger" aria-label="Stagger demo">
<ol class="motion-list"><li class="motion-list-item">Item 1</li><li class="motion-list-item">Item 2</li><li class="motion-list-item">Item 3</li><li class="motion-list-item">Item 4</li></ol>
</div>.motion-demo.motion-demo--stagger {
box-sizing: border-box;
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: 16px;
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: 16px;
box-shadow: none;
}
.motion-demo.motion-demo--stagger .motion-surface strong { font-weight: 500; }
.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: 999px;
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: 8px;
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: 16px; }
.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: 16px; 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; }
}staggerRelated items start at offset times, turning one transition into a readable sequence.
让多个项目依次播放动画,并在相邻项目之间加入短延迟,形成级联节奏。
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. |