A pure CSS dropdown that unfolds under its trigger on hover or keyboard focus, with each item dropping in a beat after the last. The panel stays clickable thanks to an invisible hover bridge.
Also known as: dropdown menu on hover css, pure css dropdown, hover dropdown animation.
<div class="hfx-dropdown-menu-stagger">
<button class="hfx-dropdown-menu-stagger-trigger" aria-haspopup="true">Products <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m6 9 6 6 6-6"/></svg></button>
<ul class="hfx-dropdown-menu-stagger-panel">
<li><a href="#"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 20v-8M11 20V5M17 20v-5M3 20h18"/></svg>Analytics</a></li>
<li><a href="#"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M13 3 5 13.5h6L10 21l8-10.5h-6z"/></svg>Automations</a></li>
<li><a href="#"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="4" y="4" width="7" height="7" rx="1.5"/><rect x="13" y="4" width="7" height="7" rx="1.5"/><rect x="4" y="13" width="7" height="7" rx="1.5"/><path d="M16.5 13.5v6M13.5 16.5h6"/></svg>Integrations</a></li>
</ul>
</div>.hfx-dropdown-menu-stagger {
--c: var(--hfx-color, #3b82f6);
font-size: var(--hfx-size, 16px);
position: relative;
display: inline-block;
margin-bottom: 8.2em; /* room for the open panel in this preview */
font-family: system-ui, sans-serif;
}
.hfx-dropdown-menu-stagger-trigger {
display: inline-flex;
align-items: center;
gap: 0.45em;
padding: 0.6em 1em;
border: 0;
border-radius: 0.6em;
background: var(--c);
color: #fff;
font: inherit;
font-weight: 600;
cursor: pointer;
}
.hfx-dropdown-menu-stagger-trigger svg {
width: 1em;
height: 1em;
transition: transform 0.3s cubic-bezier(0.3, 0.7, 0.4, 1);
}
.hfx-dropdown-menu-stagger-panel {
position: absolute;
top: calc(100% + 0.45em);
left: 50%;
width: 11.5em;
margin: 0;
padding: 0.35em;
list-style: none;
border: 1px solid rgba(0, 0, 0, 0.08);
border-radius: 0.7em;
background: #fff;
box-shadow: 0 0.9em 1.8em -0.6em rgba(15, 23, 42, 0.35);
color: #1f2937;
opacity: 0;
visibility: hidden;
transform: translateX(-50%) translateY(-0.4em) scale(0.96);
transform-origin: 50% 0;
transition: opacity 0.2s ease, transform 0.3s cubic-bezier(0.3, 0.7, 0.4, 1), visibility 0s 0.3s;
}
/* keeps the hover alive while the pointer crosses the gap */
.hfx-dropdown-menu-stagger-panel::before {
content: "";
position: absolute;
left: 0;
right: 0;
bottom: 100%;
height: 0.6em;
}
.hfx-dropdown-menu-stagger li {
opacity: 0;
transform: translateY(-0.35em);
transition: opacity 0.2s ease, transform 0.3s cubic-bezier(0.3, 0.7, 0.4, 1);
}
.hfx-dropdown-menu-stagger a {
display: flex;
align-items: center;
gap: 0.65em;
padding: 0.55em 0.7em;
border-radius: 0.45em;
color: inherit;
font-weight: 500;
text-decoration: none;
transition: background-color 0.15s ease, color 0.15s ease;
}
.hfx-dropdown-menu-stagger a svg {
width: 1.1em;
height: 1.1em;
color: var(--c);
}
.hfx-dropdown-menu-stagger a:is(:hover, :focus-visible) {
background: color-mix(in srgb, var(--c) 12%, transparent);
color: var(--c);
}
.hfx-dropdown-menu-stagger:is(:hover, :focus-within) .hfx-dropdown-menu-stagger-trigger svg { transform: rotate(180deg); }
.hfx-dropdown-menu-stagger:is(:hover, :focus-within) .hfx-dropdown-menu-stagger-panel {
opacity: 1;
visibility: visible;
transform: translateX(-50%);
transition-delay: 0s;
}
.hfx-dropdown-menu-stagger:is(:hover, :focus-within) li {
opacity: 1;
transform: none;
}
.hfx-dropdown-menu-stagger:is(:hover, :focus-within) li:nth-child(2) { transition-delay: 0.05s; }
.hfx-dropdown-menu-stagger:is(:hover, :focus-within) li:nth-child(3) { transition-delay: 0.1s; }
@media (prefers-reduced-motion: reduce) {
.hfx-dropdown-menu-stagger, .hfx-dropdown-menu-stagger *, .hfx-dropdown-menu-stagger::before, .hfx-dropdown-menu-stagger::after, .hfx-dropdown-menu-stagger *::before, .hfx-dropdown-menu-stagger *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}--hfx-color on the element or a parent.
Currently previewing #3b82f6.--hfx-size. Every other dimension is in
em, so the whole thing scales together. Currently previewing 16px.transition or animation
shorthand. Staggered delays are relative, so they keep their rhythm.