No animations match your search in this category.
The code for all 4 menus & dropdowns, explained
Every effect above, with the markup to use and the complete CSS. Each one is self-contained: paste the CSS once, add the class, done.
Dropdown Fade
A gentle pure-opacity fade — no movement at all, the calmest option. visibility joins the transition so the hidden menu can't be tabbed into by accident, and :focus-within keeps it keyboard-accessible.
Markup
<div class="fh-menu">
<button class="fh-menu-btn">Menu ▾</button>
<div class="fh-menu-list">
<a href="#">Profile</a>
<a href="#">Settings</a>
</div>
</div>
CSS
.fh-menu {
position: relative;
display: inline-block;
}
.fh-menu-btn {
padding: 10px 18px;
border: 1px solid #3a4358;
border-radius: 10px;
background: rgba(255, 255, 255, 0.05);
color: inherit;
font-weight: 600;
cursor: pointer;
}
.fh-menu-list {
position: absolute;
top: calc(100% + 6px);
left: 0;
min-width: 150px;
background: #101828;
border: 1px solid #3a4358;
border-radius: 10px;
padding: 6px;
opacity: 0;
visibility: hidden;
transition: opacity 0.3s ease, visibility 0.3s;
}
.fh-menu:hover .fh-menu-list,
.fh-menu:focus-within .fh-menu-list {
opacity: 1;
visibility: visible;
}
.fh-menu-list a {
display: block;
padding: 8px 10px;
border-radius: 6px;
color: inherit;
text-decoration: none;
font-size: 0.9em;
}
.fh-menu-list a:hover { background: rgba(6, 182, 212, 0.12); }
Dropdown Grow
The opposite personality to the fade: the menu springs out of the button corner with a visible overshoot. transform-origin: top left is the spatial cue about where it came from.
Markup
<div class="fh-menu-scale">
<button>Options ▾</button>
<div class="fh-menu-pop">…links…</div>
</div>
CSS
.fh-menu-scale {
position: relative;
display: inline-block;
}
.fh-menu-btn2 {
padding: 10px 18px;
border: 1px solid #3a4358;
border-radius: 10px;
background: rgba(255, 255, 255, 0.05);
color: inherit;
font-weight: 600;
cursor: pointer;
}
.fh-menu-pop {
position: absolute;
top: calc(100% + 6px);
left: 0;
min-width: 150px;
background: #101828;
border: 1px solid #3a4358;
border-radius: 10px;
padding: 6px;
opacity: 0;
transform: scale(0.55);
transform-origin: top left;
visibility: hidden;
transition: opacity 0.2s ease,
transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1),
visibility 0.3s;
}
.fh-menu-scale:hover .fh-menu-pop,
.fh-menu-scale:focus-within .fh-menu-pop {
opacity: 1;
transform: scale(1);
visibility: visible;
}
.fh-menu-pop a {
display: block;
padding: 8px 10px;
border-radius: 6px;
color: inherit;
text-decoration: none;
font-size: 0.9em;
}
.fh-menu-pop a:hover { background: rgba(139, 92, 246, 0.15); }
Hamburger Morph
The three bars morph into an X using :has() on a visually hidden (but still focusable) checkbox — pure CSS state. For a real navigation menu, use a button with aria-expanded and toggle a class instead, so screen readers announce whether the menu is open.
Markup
<label class="fh-burger" aria-label="Toggle menu">
<input type="checkbox" />
<span></span><span></span><span></span>
</label>
CSS
.fh-burger {
width: 46px;
height: 46px;
display: grid;
place-content: center;
gap: 5px;
border: 1px solid #3a4358;
border-radius: 10px;
cursor: pointer;
position: relative;
}
/* The checkbox covers the button invisibly, so it stays
clickable AND reachable with Tab (display: none is neither) */
.fh-burger input {
position: absolute;
inset: 0;
margin: 0;
opacity: 0;
cursor: pointer;
}
.fh-burger:has(input:focus-visible) {
outline: 2px solid #22d3ee;
outline-offset: 2px;
}
.fh-burger span {
width: 20px;
height: 2px;
background: currentColor;
border-radius: 2px;
transition: transform 0.3s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.2s ease;
}
.fh-burger:has(input:checked) span:nth-of-type(1) {
transform: translateY(7px) rotate(45deg);
}
.fh-burger:has(input:checked) span:nth-of-type(2) { opacity: 0; }
.fh-burger:has(input:checked) span:nth-of-type(3) {
transform: translateY(-7px) rotate(-45deg);
}
The visibility trick that makes dropdowns safe
The most common dropdown bug is hiding a menu with opacity: 0 alone. An element at zero opacity still occupies space, still receives clicks, and — critically — is still in the keyboard tab order and still announced by screen readers. A "closed" menu built that way silently traps keyboard users in invisible links.
The fix is to include visibility: hidden in the transition alongside opacity. Because visibility is discrete rather than continuous, it flips at the end of the transition on close and immediately on open — so the menu fades smoothly but genuinely disappears when closed. Every dropdown here uses that pattern.
Making hover menus keyboard-accessible
A dropdown that only opens on :hover is unreachable by keyboard. Adding :focus-within to the same rule fixes it in one line: the menu opens when any descendant receives focus, so tabbing into the trigger reveals it exactly as hovering does.
For production navigation, a click-triggered menu driven by JavaScript is generally better than hover — it works identically on touch, allows explicit Escape-to-close, and lets you manage aria-expanded honestly. Use the hover pattern for simple cases and progressive enhancement.
Transform origin communicates where things come from
The difference between the fade and the grow effect is spatial information. A menu that scales up from transform-origin: top left visibly emerges from its button; a menu that simply fades in appears from nowhere. The former helps users connect the panel with the control that opened it — worth the extra line for menus that open in unexpected places.
Staggering, and knowing when to stop
The staggered effect adds an incremental transition-delay per item, cascading them into view. It looks considered on a menu of three to five items and sluggish beyond that — the last item in a ten-item menu arrives long after the user has started reading. Cap the stagger, and set delays back to zero on close so the menu snaps shut instantly.