Stagger Effect
Sequential animation delays applied to a list of elements so they animate in one after another, creating a cascade or wave that communicates hierarchy and order.
Plain English
When a list of cards, menu items, or search results all appear at once, the screen feels like it flashes in — there is no sense of order or priority. Stagger fixes this by applying a small incremental delay to each element so they appear in sequence, like a deck of cards fanning out. The result reads as a wave — eye-catching, structured, and alive. Stagger works because it matches how humans naturally scan: top to bottom, left to right. The stagger direction can reinforce that reading order, guiding the eye toward the first item. The delay between each item should be short enough that the animation feels continuous (30–80ms per item) rather than slow and plodding. Longer delays work for dramatic reveals on hero sections; shorter delays work for functional list loading.
Technical
In CSS, stagger is achieved with animation-delay on each child: li:nth-child(n) { animation-delay: calc(n * 60ms); }. In Framer Motion: staggerChildren: 0.06 inside a variants object on the container, with each child using a shared variant. In React Spring, useTrail() animates an array where each item's spring starts after the previous. GSAP uses gsap.to(".item", { y: 0, stagger: 0.05 }). The stagger value should scale with list length — 60ms per item works for 5 items but for 20 items use 30ms to keep total animation under 1s. Always animate transform (translateY) + opacity, never height/top, to keep animation on the GPU compositor thread.
Live Demo
Stagger Effect
Cards animate in one by one with 100ms staggered delays — creates a sense of sequence and flow.
Stagger guides the eye — each item lands before the next appears, preventing overwhelm.
Usage
✓ Good usage
A search results page where 8 result cards stagger in top-to-bottom with 50ms delays, each sliding up 20px — the wave draws the eye downward and makes a routine list feel dynamic.
✗ Bad usage
A settings panel where every toggle, label, and divider staggers in one at a time at 100ms intervals — a 20-item list takes 2 seconds to fully appear, blocking the user from interacting with the first item.
Recommended values
- Short list (3–6 items): 60–80ms delay between items
- Medium list (7–15 items): 40–60ms delay between items
- Long list (16+ items): 20–35ms delay between items
- Total stagger duration: keep under 800ms for functional lists
- Entry transform: translateY(16–24px) + opacity 0 → 1
- Duration per item: 200–300ms ease-out
Common mistakes
- Stagger delay too long on large lists — a 100ms stagger on 30 items means the last item takes 3 seconds to appear, which feels broken rather than deliberate.
- Animating width or height instead of transform — these trigger layout recalculation on every frame and cause jank.
- Triggering stagger on every re-render (not just mount) — in React, a filter action that rerenders the list should not re-run the entrance animation on already-visible items.
AI Prompt Example
Copy this into Claude, Cursor, Bolt, or v0.
Apply a stagger entrance animation to the search results list. Each card should start at opacity: 0 and translateY: 20px, animating to opacity: 1 and translateY: 0 over 250ms with ease-out. Add a 55ms delay between each card. Use Framer Motion with a parent variants container (staggerChildren: 0.055) and child variants (hidden/visible). Wrap in a prefers-reduced-motion check — if active, skip the stagger and show all items immediately at full opacity.