Navigation✨ Premium

Stagger Menu Reveal

Adding .revealed slides each menu item from the left with a 50 ms progressive delay — spring cubic-bezier, zero animation loop.

CSSStaggerReveal

You'll get access to the interactive demo with a free account.

This effect is part of Effect.Labs — 811 vanilla effects, some free, some premium. Navigation has 36 effects, including 4 free. Explore the category →

3 usage examples

Dashboard sidebar — reveal on panel open — Stagger Menu Reveal example 1

① Dashboard sidebar — reveal on panel open

WhenThe side panel opens on login or when the user clicks the hamburger button in an app.
WhyThe left-to-right cascade follows the natural reading direction and gives the impression the panel is building itself progressively — more dynamic than a global fade-in.
Settings50 ms delay per item (default), translateX(-20px), 400 ms duration — suitable for 5–7 items before the last one feels too delayed.
Navigation dropdown — reveal on parent hover — Stagger Menu Reveal example 2

② Navigation dropdown — reveal on parent hover

WhenThe user hovers a top-level navigation item and a sub-menu of 3–5 links appears below.
WhyThe stagger visually separates each link in the group and guides the eye downward — more readable than a block that pops in all at once.
SettingsDelay reduced to 40 ms (snappier for dropdowns), translateX(-12px) for a subtler entry, 300 ms duration.
Onboarding step list — cascade on panel entry — Stagger Menu Reveal example 3

③ Onboarding step list — cascade on panel entry

WhenA 'Get started' panel opens for the first time for a new user.
WhyThe progressive stagger draws attention to each step individually, preventing the cognitive overload of a 4–5 item block appearing all at once.
Settings80 ms between steps for a slower, more deliberate pace, translateX(-24px) for a stronger entry, 450 ms duration.

How it works

The effect is entirely CSS-driven. Each .stagger-menu-item starts at opacity: 0 and transform: translateX(-20px). Adding the class .revealed to the parent container triggers the transition to opacity: 1 and translateX(0) for all items simultaneously in a single DOM operation.

The time offset (stagger) is produced by :nth-child rules: first item at 0 s, second at 50 ms, third at 100 ms, fourth at 150 ms. Each item waits for its delay before running its own 400 ms transition — the visual cascade is entirely CSS-driven, with no JavaScript scheduler.

The curve cubic-bezier(.34, 1.56, .64, 1) is a spring curve: it slightly overshoots the target value before settling, producing a characteristic elastic snap. This overshoot is more expressive than a plain ease-out for UI elements and reinforces the feeling of responsiveness.

JavaScript is limited to listening for mouseenter and mouseleave on the parent to toggle .revealed, plus a setTimeout(500 ms) that automatically reveals items on load. No requestAnimationFrame, no animation loop.

Accessibility

  • prefers-reduced-motion absent: the code contains no prefers-reduced-motion handling — animations fire regardless of OS preference. Recommended fix: wrap the transition rule in .stagger-menu-item inside a @media (prefers-reduced-motion: no-preference) block.
  • Items are <span> elements — not keyboard-focusable by default. For real navigation, replace with <a> tags or add tabindex="0" + a keydown handler (Enter / Space).
  • The trigger is mouseenter only — not accessible on touchscreens or via keyboard. The setTimeout(500 ms) auto-reveal on load mitigates the display issue but does not provide keyboard interaction.
  • No ARIA role or aria-label on the container. For accessible navigation: add role="navigation" and a descriptive aria-label on the .stagger-menu.
  • Color contrast: default text #a1a1aa on #0a0a0f ≈ 8:1 — passes WCAG AA ✓; hover text #6366f1 ≈ 4.5:1 — passes WCAG AA (borderline) ✓.

Browser compatibility

Relies solely on CSS transitions and :nth-child selectors — zero external dependencies, supported in all modern browsers since 2015.

Chrome 49+✓ Full
Firefox 44+✓ Full
Safari 9+✓ Full
Edge 16+✓ Full
Mobile iOS✓ Full
Android Chrome✓ Full

Without CSS transition support (IE 9 and below), items render statically at their final position — no JS errors, navigation remains fully functional.

The code

HTML structure to paste into your page (CSS + JS available with a premium account):

index.html — structure
<div class="stagger-menu" id="staggerMenu">
  <span class="stagger-menu-item">Item 1</span>
  <span class="stagger-menu-item">Item 2</span>
  <span class="stagger-menu-item">Item 3</span>
  <span class="stagger-menu-item">Item 4</span>
</div>
🔒 Unlock the full code — from €2.99 the first month

Full HTML + CSS + JS, copy-paste ready — with hundreds of premium effects.

Customize

Options passed to the API or data-* attributes:

Option / propertyDefaultEffect
transition-delay (nth-child) 0 / 50 / 100 / 150 ms Per-item delay in :nth-child rules — increase the step (e.g. 80 ms) for a slower stagger, reduce (30 ms) for a snappier feel. Add one rule per additional item beyond 4.
transition duration (.4s) 400 ms Duration of each individual transition in .stagger-menu-item. Shorten to 250 ms for a fast dropdown, extend to 600 ms for a cinematic effect.
cubic-bezier(.34, 1.56, .64, 1) spring / bounce Spring curve with overshoot. Replace with cubic-bezier(0, 0, 0.2, 1) for smooth ease-out without bounce, or (.68, -0.55, .27, 1.55) for stronger overshoot.
translateX(-20px) -20px Entry distance and direction in .stagger-menu-item. translateX(20px) reverses direction (right to left), translateY(10px) gives a vertical downward entry.
--text-secondary (#a1a1aa) #a1a1aa Item color at rest — modify the :root CSS variable to adapt the whole theme without touching individual rules.
hover background (rgba(99,102,241,.1)) indigo 10% Hover background in .stagger-menu-item:hover — replace with your brand color rgba (e.g. rgba(16,185,129,.1) for emerald green).
hover color (#6366f1) #6366f1 (indigo) Hover text color in .stagger-menu-item:hover — ensure ≥ 4.5:1 contrast ratio on the dark background after changing.
setTimeout delay (500 ms) 500 ms Delay before auto-reveal on load in the JS. Reduce to 200 ms for near-immediate appearance, increase to 1000 ms for a deliberate delayed reveal.

FAQ

Add as many <span class="stagger-menu-item"> elements as needed in the HTML, then add a CSS rule .stagger-menu.revealed .stagger-menu-item:nth-child(N) { transition-delay: Nx0.05s } for each additional item — for example item 5 → 0.20s, item 6 → 0.25s.
document.getElementById('staggerMenu').classList.add('revealed') to reveal, .classList.remove('revealed') to hide. Wire it to any event: modal open, load complete, route transition, API response.
Yes — removing .revealed plays the transition in reverse through the same CSS rules: items slide back left and fade out, last item first (delays naturally invert on hide). No extra code needed.