01. Tailwind Slide-Down Fade Dropdown Menu (opens in a new tab)
transition-[max-height,opacity,translate] plus one arbitrary transition-delay, and the hover bridge that keeps the menu alive across the gap is an after: strip on the group itself.22 Tailwind dropdown menus for site navigation, mega menus, and app UI — hover slide-downs, clip-path and 3D-flip reveals, glassmorphism and staggered panels, four-column and split-screen mega menus, zero-JS <details> builds, nested multi-level flyouts, command palettes, and custom selects. Scoped under .tdd-NN for no-collision pasting, prefers-reduced-motion guarded, framework-agnostic.
Related22 CSS Dropdown Menu Designs28 CSS Hamburger Menus28 Tailwind Hamburger Menus25 CSS Sticky Navigations
Premium upgradePartner: Untitled UI
Affiliate linkBuilding a whole Tailwind app, not just this component?
You just browsed 22 Tailwind dropdown menus. Untitled UI Pro unlocks 5,000+ components and sections and 250+ page examples for React, styled with Tailwind CSS v4. One licence is a one-time $349 with lifetime updates; teams start at $999.
Untitled UI React. We may earn a commission, at no extra cost to you.
transition-[max-height,opacity,translate] plus one arbitrary transition-delay, and the hover bridge that keeps the menu alive across the gap is an after: strip on the group itself.clip-path polygon animates from a zero-height strip at its top edge to the full rectangle. Both polygons live on the panel as arbitrary utilities, which is the whole argument for the port — a mismatched pair of point counts is the classic bug in this pattern, and here the pair is one line apart.perspective-[800px], transform-3d, rotate-x-90, origin-top — so the entire effect is markup, and the stylesheet holds nothing but tokens.scale-y with an overshoot curve, so it briefly overshoots its own height and settles. Porting it is mostly about the easing token — an overshoot curve is a design decision, so it belongs in @theme as --ease-tdd04, not inline as an arbitrary value.backdrop-blur-xl and backdrop-saturate-200 are real utilities, the translucent border is border-white/35, and the layered inner glow is one arbitrary shadow-[…] because a composed inset shadow is not a design-scale value.nth-child rule per item; Tailwind cannot, because variant values must be static classes. The idiomatic answer is the per-item index pattern — each link carries style="--i:2" and one shared utility reads it, so adding a sixth link means copying a line and incrementing a number.grid-cols-[1fr_1fr_1fr_1.4fr] states the whole layout in one utility, and the responsive collapse that the CSS version leaves as a to-do becomes a single max-md:grid-cols-1.after: pseudo styled entirely in utilities, and the visibility trick — the one transition Tailwind's scale genuinely cannot express — stays an arbitrary shorthand.<details> toggles itself, is keyboard operable for free, and v4 reads its state with the open: variant — so a click-to-open menu with zero JavaScript is four utilities and a marker reset.peer earns its keep: a visually hidden checkbox is the state, and peer-checked: drives both the burger-to-X morph and the panel reveal from two elements away — no ~ selectors, no stylesheet.group/l1, group/l2, group/l3 keep each level's hover from leaking into its children, which is exactly the bug the CSS version fights with > combinators.overflow-visible is load-bearing, and in utilities it sits right next to the width that makes it necessary.grid-cols-[1.2fr_1fr] holding the split. It is the demo where Tailwind's ratio tracks and per-instance overrides shine — the second panel restyles its whole billboard with a single gradient utility, no modifier class.shadow-[inset_…]) plus a raised pill (shadow-sm) is two utilities, and the whole control reads correctly without a single custom rule.after:content-[attr(data-name)] — an attr() read, in a utility.left and top, clamped to the viewport — and writes one data-open attribute. Every visual state is a data-open: variant in the markup.aria-expanded, so aria-expanded: on the button and group-has-aria-expanded: on its panel style straight off the accessibility attribute. Style and semantics cannot drift, because there is only one source of truth.transitionDelay on every item; here the delays are declarative — style="--i:3" plus one utility — and the script shrinks to a single attribute toggle.<mark>, and moving a data-active attribute down the list.focus-within: — the input ring belongs to the field wrapper, and Tailwind has a variant for exactly that — and the discipline of rendering suggestion rows from one class string the script holds, so a row's appearance is still declared in one place.aria-expanded, and the tabs style themselves from aria-selected — so the tab strip's appearance and its announcement can never disagree.<select>, with the real element still in the DOM for form submission. Options stagger in on an overshoot curve, selection is aria-selected, open state is aria-expanded — three declarative states, and a script that only moves values between them.group variant. Give the wrapper class="group", then style the panel opacity-0 invisible group-hover:opacity-100 group-hover:visible plus a transform like -translate-y-2 group-hover:translate-y-0. The slide-down fade demo is exactly this. Two things bite people: animate visibility alongside opacity or the invisible panel still eats clicks, and keep the trigger and panel edges touching — a gap between them closes the panel the instant the pointer crosses it. Add a small padding bridge (pt-2 on the panel wrapper) rather than a margin so the hover area stays continuous. Hover-only menus are fine for a mouse but strand keyboard and touch users, so reserve this pattern for secondary nav and use the ARIA or details demos when the menu is essential.opacity-0 only makes the panel transparent — it still occupies its box and still receives pointer events, so links underneath fire on the invisible layer. The fix used across these demos is to pair opacity with invisible (or hidden) and toggle both together: opacity-0 invisible group-hover:opacity-100 group-hover:visible. invisible removes it from hit-testing while keeping it in layout, which lets your transition still animate the fade; hidden removes it from layout entirely and kills any enter transition, so use it only when you don't animate. If you want the transform to animate but the panel gone when closed, add pointer-events-none group-hover:pointer-events-auto as a belt-and-braces guard. The elastic-bounce and stagger demos all layer these three utilities so the closed panel never intercepts a stray click.nth-child rule per item to offset each delay; Tailwind can't generate those in markup, so the stagger demos put the delay on each item inline. Give every link the same enter transition (opacity-0 translate-y-1 transition flipped by the parent's group-hover:) and then vary only transition-delay per item with an arbitrary value: [transition-delay:60ms], [transition-delay:120ms], and so on. The blur-entrance demo does the same but adds blur-sm group-hover:blur-0 so items crystallise rather than just slide. The common mistake is putting the delay on the container — it delays the whole group once instead of cascading. Keep the delays under roughly 250ms total or the last link feels laggy, and drop them entirely under motion-reduce: so the whole menu appears at once for anyone who has asked for reduced motion.peer lets one element style a sibling based on its state, which is how the checkbox-hack mobile nav works with no script. A visually hidden <input type="checkbox"> carries the class peer, its label is the hamburger button, and the panel that follows reacts with peer-checked:translate-x-0 (closed state -translate-x-full). group reacts to a parent's state; peer reacts to a preceding sibling's — so the input must come before the panel in source order, because CSS sibling combinators can't look backwards. Hide the input with sr-only, not hidden, or it stops being focusable and the toggle dies for keyboard users. Point the label at the input with a matching for and id so Space and Enter toggle it, and add peer-checked:rotate-90 on the icon for the open affordance.<button> carrying aria-expanded and aria-controls, and the open state is that attribute — style the panel with aria-expanded:-driven classes rather than a hover flag, so the visual and the semantics can never disagree. The native <details> and <summary> demo is the other safe default: the browser handles the toggle, focus, and Space/Enter for free, and you only style open: states. For the full menu pattern you still owe arrow-key movement, Escape to close and return focus to the trigger, and roving tabindex — a little script the demo includes. Hover-only, right-click, and pure :hover menus are mouse-only; keep those for enhancements and route anything a keyboard or screen-reader user must reach through the ARIA or details demos.<li> as a relative container and gives the child panel absolute left-full top-0 so it sits to the parent's right, revealed by that item's own group-hover:. The trick v4 makes clean is named groups: mark each level group/lvl1, group/lvl2 and react with group-hover/lvl2:, otherwise a single unnamed group opens every level at once when you hover the top item. Two gotchas: keep parent and child edges touching (use padding, not margin, as the bridge) or the flyout closes as the pointer crosses the gap, and near the viewport edge swap left-full for right-full so the last level opens leftward instead of overflowing. Deep fly-outs are hard on touch and keyboard — flatten to an accordion on small screens.<select> in the DOM for form submission and native mobile pickers, then layers a styled overlay on top for the desktop look. Don't try to replace the element — you lose the value in the submitted form, the required-field validation, and the OS picker on phones. Instead visually hide the native control (keep it focusable, not display:none), mirror its options in a styled list, and write the chosen value back to the real <select> so a normal <form> submit carries it. Wire keyboard support — Up/Down to move, Enter to choose, Escape to close — and reflect aria-expanded on the trigger. If you only need color, border and font changes, the far cheaper route is appearance-none plus a background arrow and padding on the native element, and skip the custom overlay entirely.grid grid-cols-4 gap-8 for three link groups plus a featured card, or grid-cols-[1.2fr_2fr] for a billboard column beside categorised links — so the port is mostly translating one layout line, not per-item positioning. Skip the mega menu when your nav has only a handful of destinations: a wall of columns on hover is more surface than the content justifies and it hides links behind a hover the way a simple list wouldn't. It's also punishing on touch, where there's no hover and the panel can swallow the viewport, and on keyboard, where tabbing through dozens of links per menu is slow. Reserve it for genuinely deep catalogs — retail, docs, large SaaS — collapse it to a stacked accordion under md:, and make sure every column heading is a real heading so screen-reader users can navigate by structure.32 free CSS accordions covering pure-CSS FAQ blocks with details/summary, mobile navigation menus, e-commerce filter sidebars, nested tree views, exclusive single-open groups and smoothly animated height:auto — plus 26 visual variations in vertical, horizontal and hybrid layouts. Copy-paste HTML and CSS, no JavaScript.
39 hand-coded CSS breadcrumbs — Schema.org BreadcrumbList Microdata + WCAG 2.2 accessible (Google Rich Results eligible), :has() responsive collapse, dark/light theme toggle with color-mix, Shopify/Amazon e-commerce filter chip removal, Vercel/Linear/Notion SaaS dashboard app-shell pattern, Docusaurus/Mintlify sticky scroll-shrink header, Amazon-style dropdown sibling menus, NFT/Web3 holographic shimmer (@property + conic-gradient), SaaS marketing gradient text, Airbnb filter chip with container queries, editorial blog wave underline, developer docs one-click path copy (Clipboard API), and 26 more. Semantic HTML: <nav aria-label='Breadcrumb'> + <ol> + aria-current='page'. Framework-agnostic, MIT-licensed.
26 hand-coded CSS circular and radial menu designs, from the floating-action FAB speed dial and dashboard radial hubs to game-style pie-slice wheels, SVG gooey metaball fans, hexagonal honeycombs, iris-aperture reveals, orbiting satellites on offset-path, compass-rose directional nav, sci-fi HUD rings, glassmorphism popovers built on the native Popover API, vinyl-record players, and full-takeover nebula overlays on native dialog. Every design uses CSS trigonometry (sin(), cos()) or the counter-rotation trick for positioning, ships real keyboard navigation, aria-labels on icon-only buttons, and a prefers-reduced-motion guard. Copy-paste HTML, CSS and vanilla JS with zero framework dependencies — MIT licensed.