stagger
Stagger is a GSAP property that offsets the start time of each target in a tween, animating them one after another instead of all at once. It's the single most-used tool for making a list, grid, or sequence of elements feel choreographed rather than mechanical.
- Ships in
- GSAP core
- Used in
- 5 Annnimate components
- Pairs with
- gsap.timeline()Position parameter
Updated June 1, 2026
Pick an underlined value to change it
gsap.to(".box", {y: -34,stagger: ,repeat: 1,yoyo: true,});
How stagger works
The simplest form is a number - the delay in seconds between each target's start time:
For 10 items at stagger: 0.08, the first item starts at t=0, the last at t=0.72, and the whole sequence finishes at t=0.72 + 0.6 = 1.32s.
The richer config
The two eases compose: ease: "expo.out" is the per-element animation curve, stagger.ease is how the START TIMES distribute across the set. A power2.in stagger ease makes early items cluster close together and later items spread out - useful for 'spilling outward' effects.
Use stagger for
- Reveal animations on lists, cards, or grids
- Character-by-character text reveals (paired with SplitText)
- Grid-of-tiles entrance animations
- Sequencing logo paths or SVG elements
- Anywhere 'one after another' reads better than 'all at once'
Use something else when
- Single elements - just don't pass stagger
- True asynchronous sequencing - use a GSAP timeline with explicit position parameters per tween
- Physics-based delays - stagger is deterministic; for true randomness use
from: "random"or compute delays per-target
Used in these Annnimate components
from: "start" for a left-to-right readCommon questions
- What's the difference between stagger.each and stagger.amount?
eachis the delay between each target's start (in seconds).amountis the total time the staggered set should span - GSAP calculateseachautomatically asamount / count. Useeachwhen you want a fixed rhythm regardless of count; useamountwhen you want the total animation length to stay constant as the count changes.- How do stagger.from values like 'start', 'center', 'edges' work?
- They define WHICH target gets index 0 - the one that starts first.
start(default): first child first.end: last child first.center: middle child first, rippling outward.edges: first and last simultaneously, rippling inward.random: shuffled order. For grids, you also havefrom: [0.5, 0.5]which uses normalized 2D coordinates to pick a focal point. - Why isn't my grid stagger respecting the rows/columns?
- You need to pass
stagger: { grid: [rows, cols], ... }. Withoutgrid, GSAP treats the targets as a 1D list and staggers in DOM order. Withgrid: [3, 4], GSAP knows the layout and can stagger by distance from a focal point (from: 'center') instead of by index. - Can I combine stagger with a position parameter on a timeline?
- Yes. The position parameter (
'<','>','+=0.5') decides WHEN the staggered batch starts; the stagger itself controls the rhythm within. Common pattern:tl.to(items, { ... stagger: 0.05 }, 'reveal')to fire all staggered items together with another tween labeled 'reveal'.