22 CSS Dropdown Menu Designs 06 / 22
Stagger Children Reveal Dropdown
Each menu item cascades in one-by-one with staggered animation-delay values applied via nth-child, creating a flowing sequential reveal.
The code
<div class="dd-06">
<link href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700;800&display=swap" rel="stylesheet">
<nav class="dd-06__nav">
<span class="dd-06__brand">◆ Flow</span>
<div class="dd-06__items">
<div class="dd-06__item">
<a href="#" class="dd-06__trigger">
<span>Products</span>
<span class="dd-06__arrow">▾</span>
</a>
<div class="dd-06__panel">
<a href="#" class="dd-06__link" style="--i:0"><span class="dd-06__dot" style="--c:#6366f1"></span>Design Tokens</a>
<a href="#" class="dd-06__link" style="--i:1"><span class="dd-06__dot" style="--c:#ec4899"></span>Component Kit</a>
<a href="#" class="dd-06__link" style="--i:2"><span class="dd-06__dot" style="--c:#f59e0b"></span>Icon Library</a>
<a href="#" class="dd-06__link" style="--i:3"><span class="dd-06__dot" style="--c:#10b981"></span>Figma Plugin</a>
<a href="#" class="dd-06__link" style="--i:4"><span class="dd-06__dot" style="--c:#3b82f6"></span>CLI Tools</a>
</div>
</div>
<div class="dd-06__item">
<a href="#" class="dd-06__trigger">
<span>Use Cases</span>
<span class="dd-06__arrow">▾</span>
</a>
<div class="dd-06__panel">
<a href="#" class="dd-06__link" style="--i:0"><span class="dd-06__dot" style="--c:#8b5cf6"></span>Startups</a>
<a href="#" class="dd-06__link" style="--i:1"><span class="dd-06__dot" style="--c:#06b6d4"></span>Agencies</a>
<a href="#" class="dd-06__link" style="--i:2"><span class="dd-06__dot" style="--c:#f97316"></span>Freelancers</a>
<a href="#" class="dd-06__link" style="--i:3"><span class="dd-06__dot" style="--c:#14b8a6"></span>Enterprise</a>
</div>
</div>
<div class="dd-06__item">
<a href="#" class="dd-06__trigger">
<span>Company</span>
<span class="dd-06__arrow">▾</span>
</a>
<div class="dd-06__panel">
<a href="#" class="dd-06__link" style="--i:0"><span class="dd-06__dot" style="--c:#ef4444"></span>About</a>
<a href="#" class="dd-06__link" style="--i:1"><span class="dd-06__dot" style="--c:#a855f7"></span>Blog</a>
<a href="#" class="dd-06__link" style="--i:2"><span class="dd-06__dot" style="--c:#0ea5e9"></span>Careers</a>
</div>
</div>
</div>
</nav>
</div> <div class="dd-06">
<link href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700;800&display=swap" rel="stylesheet">
<nav class="dd-06__nav">
<span class="dd-06__brand">◆ Flow</span>
<div class="dd-06__items">
<div class="dd-06__item">
<a href="#" class="dd-06__trigger">
<span>Products</span>
<span class="dd-06__arrow">▾</span>
</a>
<div class="dd-06__panel">
<a href="#" class="dd-06__link" style="--i:0"><span class="dd-06__dot" style="--c:#6366f1"></span>Design Tokens</a>
<a href="#" class="dd-06__link" style="--i:1"><span class="dd-06__dot" style="--c:#ec4899"></span>Component Kit</a>
<a href="#" class="dd-06__link" style="--i:2"><span class="dd-06__dot" style="--c:#f59e0b"></span>Icon Library</a>
<a href="#" class="dd-06__link" style="--i:3"><span class="dd-06__dot" style="--c:#10b981"></span>Figma Plugin</a>
<a href="#" class="dd-06__link" style="--i:4"><span class="dd-06__dot" style="--c:#3b82f6"></span>CLI Tools</a>
</div>
</div>
<div class="dd-06__item">
<a href="#" class="dd-06__trigger">
<span>Use Cases</span>
<span class="dd-06__arrow">▾</span>
</a>
<div class="dd-06__panel">
<a href="#" class="dd-06__link" style="--i:0"><span class="dd-06__dot" style="--c:#8b5cf6"></span>Startups</a>
<a href="#" class="dd-06__link" style="--i:1"><span class="dd-06__dot" style="--c:#06b6d4"></span>Agencies</a>
<a href="#" class="dd-06__link" style="--i:2"><span class="dd-06__dot" style="--c:#f97316"></span>Freelancers</a>
<a href="#" class="dd-06__link" style="--i:3"><span class="dd-06__dot" style="--c:#14b8a6"></span>Enterprise</a>
</div>
</div>
<div class="dd-06__item">
<a href="#" class="dd-06__trigger">
<span>Company</span>
<span class="dd-06__arrow">▾</span>
</a>
<div class="dd-06__panel">
<a href="#" class="dd-06__link" style="--i:0"><span class="dd-06__dot" style="--c:#ef4444"></span>About</a>
<a href="#" class="dd-06__link" style="--i:1"><span class="dd-06__dot" style="--c:#a855f7"></span>Blog</a>
<a href="#" class="dd-06__link" style="--i:2"><span class="dd-06__dot" style="--c:#0ea5e9"></span>Careers</a>
</div>
</div>
</div>
</nav>
</div>.dd-06, .dd-06 *, .dd-06 *::before, .dd-06 *::after {
margin: 0; padding: 0; box-sizing: border-box;
}
.dd-06 ::selection { background: #6366f1; color: #fff; }
.dd-06 {
--surface: #fff;
--text: #1e293b;
--border: #f1f5f9;
--hover: #f8fafc;
font-family: 'Nunito', sans-serif;
min-height: 360px;
display: flex;
align-items: flex-start;
justify-content: center;
padding: 32px 20px;
background: linear-gradient(135deg, #f0fdf4 0%, #ecfdf5 50%, #f0f9ff 100%);
}
.dd-06__nav {
display: flex;
align-items: center;
gap: 4px;
background: var(--surface);
border: 1px solid #e2e8f0;
border-radius: 14px;
padding: 10px 10px 10px 20px;
box-shadow: 0 4px 20px rgba(0,0,0,.06);
position: relative;
z-index: 100;
}
.dd-06__brand {
font-size: 17px;
font-weight: 800;
color: #6366f1;
margin-right: 12px;
letter-spacing: -0.3px;
}
.dd-06__items { display: flex; gap: 2px; }
.dd-06__item { position: relative; }
.dd-06__item::after {
content: "";
position: absolute;
left: 0; right: 0;
top: 100%;
height: 10px;
/* hover-bridge: invisible strip below the trigger covering
the visible gap before the panel. Lives on .__item (not
the panel, which has overflow:hidden / pointer-events:
none in its closed state) so the parent :hover stays
active while the cursor traverses the gap. */
}
.dd-06__trigger {
display: flex;
align-items: center;
gap: 6px;
padding: 8px 14px;
border-radius: 10px;
color: var(--text);
text-decoration: none;
font-size: 14px;
font-weight: 600;
transition: background 0.15s, color 0.15s;
}
.dd-06__trigger:hover, .dd-06__item:hover .dd-06__trigger {
background: #eef2ff;
color: #6366f1;
}
.dd-06__arrow {
font-size: 12px;
transition: transform 0.22s ease;
color: #94a3b8;
}
.dd-06__item:hover .dd-06__arrow { transform: rotate(180deg); color: #6366f1; }
/* panel */
.dd-06__panel {
position: absolute;
top: calc(100% + 10px);
left: 50%;
transform: translateX(-50%);
min-width: 200px;
background: var(--surface);
border: 1px solid #e2e8f0;
border-radius: 14px;
box-shadow: 0 12px 40px rgba(0,0,0,.10);
padding: 8px;
display: flex;
flex-direction: column;
gap: 2px;
opacity: 0;
pointer-events: none;
transition: opacity 0.18s ease;
}
.dd-06__item:hover .dd-06__panel {
opacity: 1;
pointer-events: auto;
}
/* stagger children */
@keyframes dd-06-slide-in {
from { opacity: 0; transform: translateX(-10px); }
to { opacity: 1; transform: translateX(0); }
}
.dd-06__link {
display: flex;
align-items: center;
gap: 10px;
padding: 9px 12px;
border-radius: 10px;
text-decoration: none;
color: var(--text);
font-size: 13.5px;
font-weight: 600;
opacity: 0;
transition: background 0.15s;
}
.dd-06__item:hover .dd-06__link {
animation: dd-06-slide-in 0.32s cubic-bezier(0.16, 1, 0.3, 1) forwards;
animation-delay: calc(var(--i) * 60ms);
}
.dd-06__link:hover { background: var(--hover); }
.dd-06__dot {
width: 8px;
height: 8px;
border-radius: 50%;
background: var(--c, #6366f1);
flex-shrink: 0;
}
@media (prefers-reduced-motion: reduce) {
.dd-06__link { animation: none; opacity: 1; }
.dd-06__panel { transition: none; }
} .dd-06, .dd-06 *, .dd-06 *::before, .dd-06 *::after {
margin: 0; padding: 0; box-sizing: border-box;
}
.dd-06 ::selection { background: #6366f1; color: #fff; }
.dd-06 {
--surface: #fff;
--text: #1e293b;
--border: #f1f5f9;
--hover: #f8fafc;
font-family: 'Nunito', sans-serif;
min-height: 360px;
display: flex;
align-items: flex-start;
justify-content: center;
padding: 32px 20px;
background: linear-gradient(135deg, #f0fdf4 0%, #ecfdf5 50%, #f0f9ff 100%);
}
.dd-06__nav {
display: flex;
align-items: center;
gap: 4px;
background: var(--surface);
border: 1px solid #e2e8f0;
border-radius: 14px;
padding: 10px 10px 10px 20px;
box-shadow: 0 4px 20px rgba(0,0,0,.06);
position: relative;
z-index: 100;
}
.dd-06__brand {
font-size: 17px;
font-weight: 800;
color: #6366f1;
margin-right: 12px;
letter-spacing: -0.3px;
}
.dd-06__items { display: flex; gap: 2px; }
.dd-06__item { position: relative; }
.dd-06__item::after {
content: "";
position: absolute;
left: 0; right: 0;
top: 100%;
height: 10px;
/* hover-bridge: invisible strip below the trigger covering
the visible gap before the panel. Lives on .__item (not
the panel, which has overflow:hidden / pointer-events:
none in its closed state) so the parent :hover stays
active while the cursor traverses the gap. */
}
.dd-06__trigger {
display: flex;
align-items: center;
gap: 6px;
padding: 8px 14px;
border-radius: 10px;
color: var(--text);
text-decoration: none;
font-size: 14px;
font-weight: 600;
transition: background 0.15s, color 0.15s;
}
.dd-06__trigger:hover, .dd-06__item:hover .dd-06__trigger {
background: #eef2ff;
color: #6366f1;
}
.dd-06__arrow {
font-size: 12px;
transition: transform 0.22s ease;
color: #94a3b8;
}
.dd-06__item:hover .dd-06__arrow { transform: rotate(180deg); color: #6366f1; }
/* panel */
.dd-06__panel {
position: absolute;
top: calc(100% + 10px);
left: 50%;
transform: translateX(-50%);
min-width: 200px;
background: var(--surface);
border: 1px solid #e2e8f0;
border-radius: 14px;
box-shadow: 0 12px 40px rgba(0,0,0,.10);
padding: 8px;
display: flex;
flex-direction: column;
gap: 2px;
opacity: 0;
pointer-events: none;
transition: opacity 0.18s ease;
}
.dd-06__item:hover .dd-06__panel {
opacity: 1;
pointer-events: auto;
}
/* stagger children */
@keyframes dd-06-slide-in {
from { opacity: 0; transform: translateX(-10px); }
to { opacity: 1; transform: translateX(0); }
}
.dd-06__link {
display: flex;
align-items: center;
gap: 10px;
padding: 9px 12px;
border-radius: 10px;
text-decoration: none;
color: var(--text);
font-size: 13.5px;
font-weight: 600;
opacity: 0;
transition: background 0.15s;
}
.dd-06__item:hover .dd-06__link {
animation: dd-06-slide-in 0.32s cubic-bezier(0.16, 1, 0.3, 1) forwards;
animation-delay: calc(var(--i) * 60ms);
}
.dd-06__link:hover { background: var(--hover); }
.dd-06__dot {
width: 8px;
height: 8px;
border-radius: 50%;
background: var(--c, #6366f1);
flex-shrink: 0;
}
@media (prefers-reduced-motion: reduce) {
.dd-06__link { animation: none; opacity: 1; }
.dd-06__panel { transition: none; }
}How this works
The panel wrapper uses a simple opacity 0 → 1 and translateY(-4px) → translateY(0) to appear, but the real effect is on the children. Each .dd-06__link starts with opacity: 0; transform: translateX(-10px) and is assigned an animation that runs when the parent triggers. The key is animation-delay: calc(var(--i) * 60ms) where --i is set via inline style="--i:0" through --i:4 on each child.
Each child plays the dd-06-slide-in keyframe — a simple left-slide + fade — but only when the parent container gets the :hover state applied via the ancestor :hover .dd-06__panel .dd-06__link selector. The animation-fill-mode: both ensures items stay at their end state and don't flash back to hidden after the animation completes.
Customize
- Speed up the cascade by reducing the stagger increment from
60msto40msin thecalc()expression on each child's delay. - Change the slide direction from left to bottom by using
translateY(10px)in the keyframe instead oftranslateX(-10px). - Add exit animation by targeting
:not(:hover)states with a reverse keyframe — though this requires JS class toggling for reliable cross-browser behavior. - Use the same technique on icon child elements inside each link for a secondary micro-stagger within each row.
Watch out for
- CSS animations on hover reset every time the hover state re-triggers — quickly mousing in and out causes items to replay from the start. Use JS class toggling to prevent replays.
animation-delaywith negative values (e.g.-0.1s) starts the animation mid-playthrough — useful for making early items appear faster.- The
animation-fill-mode: bothis crucial — without it, items flash invisible before their delay elapses and again after the animation finishes.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 43+ | 9+ | 16+ | 43+ |
CSS custom properties as animation delays are supported in all modern browsers.