02 / 15
All 15 in 15 Tailwind CSS Navigation Menus
- 01Tailwind CSS Navbar with Animated Hover Underline
- 02Tailwind CSS Dropdown Menu — Hover & Keyboard Accessible
- 03Tailwind CSS Mega Menu Navigation
- 04Tailwind CSS Hamburger Menu with Slide-Out Drawer
- 05Tailwind CSS Full-Screen Overlay Menu
- 06Tailwind CSS Sticky Navbar That Shrinks on Scroll
- 07Tailwind CSS Collapsible Sidebar Navigation
- 08Tailwind CSS Tabs with Animated Sliding Indicator
- 09Tailwind CSS Breadcrumb Navigation Examples
- 10Glassmorphism Navbar in Tailwind CSS
- 11Tailwind CSS Mobile Bottom Navigation Bar with Animated Icons
- 12Tailwind CSS Multi-Level Accordion Sidebar Menu
- 13Tailwind CSS Navbar with Magnetic Hover Effect
- 14Tailwind CSS Neon Glow Navigation Menu
- 15Tailwind CSS Animated Pill Navigation Indicator
Tailwind CSS Dropdown Menu — Hover & Keyboard Accessible
A product-site navbar with rich dropdowns — a two-column panel with icon tiles, a compact list and a resources menu — that open on group-hover/dd: and, just as importantly, on group-focus-within/dd: so keyboard users get the same menu. An invisible hover bridge fixes the classic ‘menu closes when you move to it’ bug. Zero JavaScript.
Nucleo: 44,000+ SVG icons in five families · All Icons Bundle $149
Nucleo · Affiliate link
The code
<div class="tnv-02 min-h-svh w-full bg-tnv02-bg bg-[radial-gradient(80%_60%_at_50%_0%,white,transparent)] font-tnv02-sans text-tnv02-ink antialiased selection:bg-tnv02-acc selection:text-white">
<header class="sticky top-0 z-30 border-b border-tnv02-line bg-white/90 shadow-[0_2px_20px_-8px_var(--color-tnv02-shadow)] backdrop-blur-md">
<nav aria-label="Main" class="mx-auto flex h-[68px] max-w-6xl items-center justify-between gap-6 px-5 sm:px-10">
<a href="#" class="flex items-center gap-2.5 text-xl font-bold tracking-[-0.03em]">
<span class="grid size-8 place-items-center rounded-lg bg-linear-135 from-tnv02-acc to-tnv02-acc2 shadow-[0_4px_12px_-4px_var(--color-tnv02-acc)]"><svg class="size-[18px] fill-white" viewBox="0 0 24 24" aria-hidden="true"><path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"/></svg></span>Vertex
</a>
<ul class="hidden items-center gap-0.5 md:flex">
<li class="group/dd relative">
<button type="button" aria-haspopup="true" class="flex h-11 items-center gap-1.5 rounded-lg px-3.5 text-sm font-semibold text-tnv02-mut transition-colors group-hover/dd:bg-tnv02-bg group-hover/dd:text-tnv02-ink group-focus-within/dd:bg-tnv02-bg group-focus-within/dd:text-tnv02-ink focus-visible:outline-2 focus-visible:outline-tnv02-acc">Products<svg class="size-3.5 opacity-60 transition-transform duration-200 group-hover/dd:rotate-180 group-focus-within/dd:rotate-180" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M6 9l6 6 6-6"/></svg></button>
<div class="invisible absolute top-full left-1/2 z-40 mt-2.5 grid w-[30rem] -translate-x-1/2 translate-y-1.5 grid-cols-2 gap-1 rounded-2xl border border-tnv02-line bg-white p-2 opacity-0 shadow-[0_24px_60px_-16px_var(--color-tnv02-shadow)] transition-[opacity,translate,visibility] duration-200 ease-[cubic-bezier(.16,1,.3,1)] before:absolute before:inset-x-0 before:-top-3 before:h-3 before:content-[''] group-hover/dd:visible group-hover/dd:translate-y-0 group-hover/dd:opacity-100 group-focus-within/dd:visible group-focus-within/dd:translate-y-0 group-focus-within/dd:opacity-100 motion-reduce:transition-none">
<a href="#" class="group/it flex items-center gap-3 rounded-xl p-3 outline-none transition-colors hover:bg-tnv02-bg focus-visible:bg-tnv02-bg focus-visible:ring-2 focus-visible:ring-tnv02-acc/40"><span class="grid size-10 flex-none place-items-center rounded-lg bg-tnv02-bg text-tnv02-acc transition-colors group-hover/it:bg-tnv02-acc group-hover/it:text-white"><svg class="size-[18px]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><rect x="3" y="3" width="7" height="7" rx="1.5"/><rect x="14" y="3" width="7" height="7" rx="1.5"/><rect x="3" y="14" width="7" height="7" rx="1.5"/><rect x="14" y="14" width="7" height="7" rx="1.5"/></svg></span><span class="grid text-sm font-semibold">Dashboard<span class="text-xs font-medium text-tnv02-mut">Analytics & insights</span></span></a>
<a href="#" class="group/it flex items-center gap-3 rounded-xl p-3 outline-none transition-colors hover:bg-tnv02-bg focus-visible:bg-tnv02-bg focus-visible:ring-2 focus-visible:ring-tnv02-acc/40"><span class="grid size-10 flex-none place-items-center rounded-lg bg-tnv02-bg text-tnv02-acc transition-colors group-hover/it:bg-tnv02-acc group-hover/it:text-white"><svg class="size-[18px]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M22 12h-4l-3 9L9 3l-3 9H2"/></svg></span><span class="grid text-sm font-semibold">Monitoring<span class="text-xs font-medium text-tnv02-mut">Real-time metrics</span></span></a>
<a href="#" class="group/it flex items-center gap-3 rounded-xl p-3 outline-none transition-colors hover:bg-tnv02-bg focus-visible:bg-tnv02-bg focus-visible:ring-2 focus-visible:ring-tnv02-acc/40"><span class="grid size-10 flex-none place-items-center rounded-lg bg-tnv02-bg text-tnv02-acc transition-colors group-hover/it:bg-tnv02-acc group-hover/it:text-white"><svg class="size-[18px]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M17 21v-2a4 4 0 00-4-4H5a4 4 0 00-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 00-3-3.87M16 3.13a4 4 0 010 7.75"/></svg></span><span class="grid text-sm font-semibold">Teams<span class="text-xs font-medium text-tnv02-mut">Collaboration tools</span></span></a>
<a href="#" class="group/it flex items-center gap-3 rounded-xl p-3 outline-none transition-colors hover:bg-tnv02-bg focus-visible:bg-tnv02-bg focus-visible:ring-2 focus-visible:ring-tnv02-acc/40"><span class="grid size-10 flex-none place-items-center rounded-lg bg-tnv02-bg text-tnv02-acc transition-colors group-hover/it:bg-tnv02-acc group-hover/it:text-white"><svg class="size-[18px]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z"/></svg></span><span class="grid text-sm font-semibold"><span class="flex items-center gap-1.5">Automation<span class="rounded-full bg-tnv02-acc/10 px-1.5 py-px text-[10px] font-bold tracking-wide text-tnv02-acc uppercase">New</span></span><span class="text-xs font-medium text-tnv02-mut">Workflow builder</span></span></a>
<a href="#" class="col-span-2 mt-1 flex min-h-11 items-center justify-between rounded-xl bg-linear-135 from-tnv02-bg to-tnv02-line px-4 py-3 text-[13px] font-bold text-tnv02-acc transition hover:brightness-[0.97] focus-visible:outline-2 focus-visible:outline-tnv02-acc">Explore all products<svg class="size-4 transition-transform group-hover/dd:translate-x-0.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M5 12h14M12 5l7 7-7 7"/></svg></a>
</div>
</li>
<li class="group/dd relative">
<button type="button" aria-haspopup="true" class="flex h-11 items-center gap-1.5 rounded-lg px-3.5 text-sm font-semibold text-tnv02-mut transition-colors group-hover/dd:bg-tnv02-bg group-hover/dd:text-tnv02-ink group-focus-within/dd:bg-tnv02-bg group-focus-within/dd:text-tnv02-ink focus-visible:outline-2 focus-visible:outline-tnv02-acc">Solutions<svg class="size-3.5 opacity-60 transition-transform duration-200 group-hover/dd:rotate-180 group-focus-within/dd:rotate-180" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M6 9l6 6 6-6"/></svg></button>
<ul class="invisible absolute top-full left-1/2 z-40 mt-2.5 grid w-56 -translate-x-1/2 translate-y-1.5 gap-0.5 rounded-2xl border border-tnv02-line bg-white p-2 text-sm font-semibold text-tnv02-mut opacity-0 shadow-[0_24px_60px_-16px_var(--color-tnv02-shadow)] transition-[opacity,translate,visibility] duration-200 ease-[cubic-bezier(.16,1,.3,1)] before:absolute before:inset-x-0 before:-top-3 before:h-3 before:content-[''] group-hover/dd:visible group-hover/dd:translate-y-0 group-hover/dd:opacity-100 group-focus-within/dd:visible group-focus-within/dd:translate-y-0 group-focus-within/dd:opacity-100 motion-reduce:transition-none [&_a]:flex [&_a]:min-h-11 [&_a]:items-center [&_a]:rounded-lg [&_a]:px-3 [&_a]:outline-none [&_a:focus-visible]:bg-tnv02-bg [&_a:focus-visible]:text-tnv02-ink [&_a:hover]:bg-tnv02-bg [&_a:hover]:text-tnv02-ink">
<li><a href="#">Enterprise</a></li>
<li><a href="#">Startups</a></li>
<li><a href="#">Agencies</a></li>
<li role="separator" class="mx-2 my-1 h-px bg-tnv02-line"></li>
<li><a href="#">Case studies</a></li>
</ul>
</li>
<li><a href="#" class="flex h-11 items-center rounded-lg px-3.5 text-sm font-semibold text-tnv02-mut transition-colors hover:bg-tnv02-bg hover:text-tnv02-ink focus-visible:outline-2 focus-visible:outline-tnv02-acc">Pricing</a></li>
<li class="group/dd relative">
<button type="button" aria-haspopup="true" class="flex h-11 items-center gap-1.5 rounded-lg px-3.5 text-sm font-semibold text-tnv02-mut transition-colors group-hover/dd:bg-tnv02-bg group-hover/dd:text-tnv02-ink group-focus-within/dd:bg-tnv02-bg group-focus-within/dd:text-tnv02-ink focus-visible:outline-2 focus-visible:outline-tnv02-acc">Resources<svg class="size-3.5 opacity-60 transition-transform duration-200 group-hover/dd:rotate-180 group-focus-within/dd:rotate-180" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M6 9l6 6 6-6"/></svg></button>
<ul class="invisible absolute top-full left-1/2 z-40 mt-2.5 grid w-56 -translate-x-1/2 translate-y-1.5 gap-0.5 rounded-2xl border border-tnv02-line bg-white p-2 text-sm font-semibold text-tnv02-mut opacity-0 shadow-[0_24px_60px_-16px_var(--color-tnv02-shadow)] transition-[opacity,translate,visibility] duration-200 ease-[cubic-bezier(.16,1,.3,1)] before:absolute before:inset-x-0 before:-top-3 before:h-3 before:content-[''] group-hover/dd:visible group-hover/dd:translate-y-0 group-hover/dd:opacity-100 group-focus-within/dd:visible group-focus-within/dd:translate-y-0 group-focus-within/dd:opacity-100 motion-reduce:transition-none [&_a]:flex [&_a]:min-h-11 [&_a]:items-center [&_a]:justify-between [&_a]:rounded-lg [&_a]:px-3 [&_a]:outline-none [&_a:focus-visible]:bg-tnv02-bg [&_a:focus-visible]:text-tnv02-ink [&_a:hover]:bg-tnv02-bg [&_a:hover]:text-tnv02-ink">
<li><a href="#">Documentation<kbd class="font-tnv02-mono text-[11px] font-medium text-tnv02-mut">D</kbd></a></li>
<li><a href="#">Blog</a></li>
<li><a href="#">Community</a></li>
</ul>
</li>
</ul>
<div class="flex items-center gap-2.5">
<a href="#" class="hidden h-10 items-center rounded-lg border-[1.5px] border-tnv02-line px-4 text-sm font-semibold text-tnv02-acc transition hover:border-tnv02-acc2 hover:bg-tnv02-bg focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tnv02-acc sm:inline-flex">Log in</a>
<a href="#" class="inline-flex h-10 items-center rounded-lg bg-tnv02-acc px-4 text-sm font-semibold text-white shadow-[0_6px_16px_-6px_var(--color-tnv02-acc)] transition hover:brightness-110 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tnv02-acc">Start free</a>
<details class="group/m relative md:hidden">
<summary aria-label="Menu" class="grid size-11 cursor-pointer list-none place-items-center rounded-lg border border-tnv02-line bg-white outline-none focus-visible:ring-2 focus-visible:ring-tnv02-acc/40 [&::-webkit-details-marker]:hidden"><svg class="size-5 group-open/m:hidden" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M4 7h16M4 12h16M4 17h10"/></svg><svg class="hidden size-5 group-open/m:block" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M6 6l12 12M18 6L6 18"/></svg></summary>
<ul class="absolute top-[calc(100%+10px)] right-0 z-40 grid w-64 gap-0.5 rounded-2xl border border-tnv02-line bg-white p-2 text-[15px] font-semibold shadow-[0_24px_60px_-16px_var(--color-tnv02-shadow)] transition-[opacity,translate] duration-200 starting:-translate-y-1 starting:opacity-0 [&_a]:flex [&_a]:min-h-11 [&_a]:items-center [&_a]:rounded-lg [&_a]:px-3 [&_a:hover]:bg-tnv02-bg">
<li><a href="#">Products</a></li><li><a href="#">Solutions</a></li><li><a href="#">Pricing</a></li><li><a href="#">Resources</a></li><li><a href="#" class="text-tnv02-acc">Log in</a></li>
</ul>
</details>
</div>
</nav>
</header>
<main class="grid place-items-center px-5 py-24 text-center [&_code]:rounded [&_code]:bg-tnv02-line [&_code]:px-1.5 [&_code]:font-tnv02-mono [&_code]:text-[0.85em] [&_code]:text-tnv02-ink">
<span class="mb-6 inline-flex items-center gap-2 rounded-full bg-tnv02-acc py-1 pr-3 pl-1 text-xs font-bold text-white"><span class="grid size-5 place-items-center rounded-full bg-white/25"><span class="size-1.5 rounded-full bg-white"></span></span>Hover or Tab to any item with an arrow</span>
<h1 class="max-w-2xl text-[clamp(2.25rem,5vw,3.5rem)] leading-[1.1] font-extrabold tracking-[-0.035em] text-balance">Dropdowns that stay open when you reach for them</h1>
<p class="mt-4 max-w-lg text-base/[1.7] text-tnv02-mut text-pretty">Panels open on <code>group-hover/dd:</code> <em>and</em> <code>group-focus-within/dd:</code>, slide in with <code>translate-y</code>, and an invisible bridge stops them closing as the pointer crosses the gap.</p>
</main>
</div><div class="tnv-02 min-h-svh w-full bg-tnv02-bg bg-[radial-gradient(80%_60%_at_50%_0%,white,transparent)] font-tnv02-sans text-tnv02-ink antialiased selection:bg-tnv02-acc selection:text-white">
<header class="sticky top-0 z-30 border-b border-tnv02-line bg-white/90 shadow-[0_2px_20px_-8px_var(--color-tnv02-shadow)] backdrop-blur-md">
<nav aria-label="Main" class="mx-auto flex h-[68px] max-w-6xl items-center justify-between gap-6 px-5 sm:px-10">
<a href="#" class="flex items-center gap-2.5 text-xl font-bold tracking-[-0.03em]">
<span class="grid size-8 place-items-center rounded-lg bg-linear-135 from-tnv02-acc to-tnv02-acc2 shadow-[0_4px_12px_-4px_var(--color-tnv02-acc)]"><svg class="size-[18px] fill-white" viewBox="0 0 24 24" aria-hidden="true"><path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"/></svg></span>Vertex
</a>
<ul class="hidden items-center gap-0.5 md:flex">
<li class="group/dd relative">
<button type="button" aria-haspopup="true" class="flex h-11 items-center gap-1.5 rounded-lg px-3.5 text-sm font-semibold text-tnv02-mut transition-colors group-hover/dd:bg-tnv02-bg group-hover/dd:text-tnv02-ink group-focus-within/dd:bg-tnv02-bg group-focus-within/dd:text-tnv02-ink focus-visible:outline-2 focus-visible:outline-tnv02-acc">Products<svg class="size-3.5 opacity-60 transition-transform duration-200 group-hover/dd:rotate-180 group-focus-within/dd:rotate-180" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M6 9l6 6 6-6"/></svg></button>
<div class="invisible absolute top-full left-1/2 z-40 mt-2.5 grid w-[30rem] -translate-x-1/2 translate-y-1.5 grid-cols-2 gap-1 rounded-2xl border border-tnv02-line bg-white p-2 opacity-0 shadow-[0_24px_60px_-16px_var(--color-tnv02-shadow)] transition-[opacity,translate,visibility] duration-200 ease-[cubic-bezier(.16,1,.3,1)] before:absolute before:inset-x-0 before:-top-3 before:h-3 before:content-[''] group-hover/dd:visible group-hover/dd:translate-y-0 group-hover/dd:opacity-100 group-focus-within/dd:visible group-focus-within/dd:translate-y-0 group-focus-within/dd:opacity-100 motion-reduce:transition-none">
<a href="#" class="group/it flex items-center gap-3 rounded-xl p-3 outline-none transition-colors hover:bg-tnv02-bg focus-visible:bg-tnv02-bg focus-visible:ring-2 focus-visible:ring-tnv02-acc/40"><span class="grid size-10 flex-none place-items-center rounded-lg bg-tnv02-bg text-tnv02-acc transition-colors group-hover/it:bg-tnv02-acc group-hover/it:text-white"><svg class="size-[18px]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><rect x="3" y="3" width="7" height="7" rx="1.5"/><rect x="14" y="3" width="7" height="7" rx="1.5"/><rect x="3" y="14" width="7" height="7" rx="1.5"/><rect x="14" y="14" width="7" height="7" rx="1.5"/></svg></span><span class="grid text-sm font-semibold">Dashboard<span class="text-xs font-medium text-tnv02-mut">Analytics & insights</span></span></a>
<a href="#" class="group/it flex items-center gap-3 rounded-xl p-3 outline-none transition-colors hover:bg-tnv02-bg focus-visible:bg-tnv02-bg focus-visible:ring-2 focus-visible:ring-tnv02-acc/40"><span class="grid size-10 flex-none place-items-center rounded-lg bg-tnv02-bg text-tnv02-acc transition-colors group-hover/it:bg-tnv02-acc group-hover/it:text-white"><svg class="size-[18px]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M22 12h-4l-3 9L9 3l-3 9H2"/></svg></span><span class="grid text-sm font-semibold">Monitoring<span class="text-xs font-medium text-tnv02-mut">Real-time metrics</span></span></a>
<a href="#" class="group/it flex items-center gap-3 rounded-xl p-3 outline-none transition-colors hover:bg-tnv02-bg focus-visible:bg-tnv02-bg focus-visible:ring-2 focus-visible:ring-tnv02-acc/40"><span class="grid size-10 flex-none place-items-center rounded-lg bg-tnv02-bg text-tnv02-acc transition-colors group-hover/it:bg-tnv02-acc group-hover/it:text-white"><svg class="size-[18px]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M17 21v-2a4 4 0 00-4-4H5a4 4 0 00-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 00-3-3.87M16 3.13a4 4 0 010 7.75"/></svg></span><span class="grid text-sm font-semibold">Teams<span class="text-xs font-medium text-tnv02-mut">Collaboration tools</span></span></a>
<a href="#" class="group/it flex items-center gap-3 rounded-xl p-3 outline-none transition-colors hover:bg-tnv02-bg focus-visible:bg-tnv02-bg focus-visible:ring-2 focus-visible:ring-tnv02-acc/40"><span class="grid size-10 flex-none place-items-center rounded-lg bg-tnv02-bg text-tnv02-acc transition-colors group-hover/it:bg-tnv02-acc group-hover/it:text-white"><svg class="size-[18px]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z"/></svg></span><span class="grid text-sm font-semibold"><span class="flex items-center gap-1.5">Automation<span class="rounded-full bg-tnv02-acc/10 px-1.5 py-px text-[10px] font-bold tracking-wide text-tnv02-acc uppercase">New</span></span><span class="text-xs font-medium text-tnv02-mut">Workflow builder</span></span></a>
<a href="#" class="col-span-2 mt-1 flex min-h-11 items-center justify-between rounded-xl bg-linear-135 from-tnv02-bg to-tnv02-line px-4 py-3 text-[13px] font-bold text-tnv02-acc transition hover:brightness-[0.97] focus-visible:outline-2 focus-visible:outline-tnv02-acc">Explore all products<svg class="size-4 transition-transform group-hover/dd:translate-x-0.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M5 12h14M12 5l7 7-7 7"/></svg></a>
</div>
</li>
<li class="group/dd relative">
<button type="button" aria-haspopup="true" class="flex h-11 items-center gap-1.5 rounded-lg px-3.5 text-sm font-semibold text-tnv02-mut transition-colors group-hover/dd:bg-tnv02-bg group-hover/dd:text-tnv02-ink group-focus-within/dd:bg-tnv02-bg group-focus-within/dd:text-tnv02-ink focus-visible:outline-2 focus-visible:outline-tnv02-acc">Solutions<svg class="size-3.5 opacity-60 transition-transform duration-200 group-hover/dd:rotate-180 group-focus-within/dd:rotate-180" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M6 9l6 6 6-6"/></svg></button>
<ul class="invisible absolute top-full left-1/2 z-40 mt-2.5 grid w-56 -translate-x-1/2 translate-y-1.5 gap-0.5 rounded-2xl border border-tnv02-line bg-white p-2 text-sm font-semibold text-tnv02-mut opacity-0 shadow-[0_24px_60px_-16px_var(--color-tnv02-shadow)] transition-[opacity,translate,visibility] duration-200 ease-[cubic-bezier(.16,1,.3,1)] before:absolute before:inset-x-0 before:-top-3 before:h-3 before:content-[''] group-hover/dd:visible group-hover/dd:translate-y-0 group-hover/dd:opacity-100 group-focus-within/dd:visible group-focus-within/dd:translate-y-0 group-focus-within/dd:opacity-100 motion-reduce:transition-none [&_a]:flex [&_a]:min-h-11 [&_a]:items-center [&_a]:rounded-lg [&_a]:px-3 [&_a]:outline-none [&_a:focus-visible]:bg-tnv02-bg [&_a:focus-visible]:text-tnv02-ink [&_a:hover]:bg-tnv02-bg [&_a:hover]:text-tnv02-ink">
<li><a href="#">Enterprise</a></li>
<li><a href="#">Startups</a></li>
<li><a href="#">Agencies</a></li>
<li role="separator" class="mx-2 my-1 h-px bg-tnv02-line"></li>
<li><a href="#">Case studies</a></li>
</ul>
</li>
<li><a href="#" class="flex h-11 items-center rounded-lg px-3.5 text-sm font-semibold text-tnv02-mut transition-colors hover:bg-tnv02-bg hover:text-tnv02-ink focus-visible:outline-2 focus-visible:outline-tnv02-acc">Pricing</a></li>
<li class="group/dd relative">
<button type="button" aria-haspopup="true" class="flex h-11 items-center gap-1.5 rounded-lg px-3.5 text-sm font-semibold text-tnv02-mut transition-colors group-hover/dd:bg-tnv02-bg group-hover/dd:text-tnv02-ink group-focus-within/dd:bg-tnv02-bg group-focus-within/dd:text-tnv02-ink focus-visible:outline-2 focus-visible:outline-tnv02-acc">Resources<svg class="size-3.5 opacity-60 transition-transform duration-200 group-hover/dd:rotate-180 group-focus-within/dd:rotate-180" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M6 9l6 6 6-6"/></svg></button>
<ul class="invisible absolute top-full left-1/2 z-40 mt-2.5 grid w-56 -translate-x-1/2 translate-y-1.5 gap-0.5 rounded-2xl border border-tnv02-line bg-white p-2 text-sm font-semibold text-tnv02-mut opacity-0 shadow-[0_24px_60px_-16px_var(--color-tnv02-shadow)] transition-[opacity,translate,visibility] duration-200 ease-[cubic-bezier(.16,1,.3,1)] before:absolute before:inset-x-0 before:-top-3 before:h-3 before:content-[''] group-hover/dd:visible group-hover/dd:translate-y-0 group-hover/dd:opacity-100 group-focus-within/dd:visible group-focus-within/dd:translate-y-0 group-focus-within/dd:opacity-100 motion-reduce:transition-none [&_a]:flex [&_a]:min-h-11 [&_a]:items-center [&_a]:justify-between [&_a]:rounded-lg [&_a]:px-3 [&_a]:outline-none [&_a:focus-visible]:bg-tnv02-bg [&_a:focus-visible]:text-tnv02-ink [&_a:hover]:bg-tnv02-bg [&_a:hover]:text-tnv02-ink">
<li><a href="#">Documentation<kbd class="font-tnv02-mono text-[11px] font-medium text-tnv02-mut">D</kbd></a></li>
<li><a href="#">Blog</a></li>
<li><a href="#">Community</a></li>
</ul>
</li>
</ul>
<div class="flex items-center gap-2.5">
<a href="#" class="hidden h-10 items-center rounded-lg border-[1.5px] border-tnv02-line px-4 text-sm font-semibold text-tnv02-acc transition hover:border-tnv02-acc2 hover:bg-tnv02-bg focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tnv02-acc sm:inline-flex">Log in</a>
<a href="#" class="inline-flex h-10 items-center rounded-lg bg-tnv02-acc px-4 text-sm font-semibold text-white shadow-[0_6px_16px_-6px_var(--color-tnv02-acc)] transition hover:brightness-110 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tnv02-acc">Start free</a>
<details class="group/m relative md:hidden">
<summary aria-label="Menu" class="grid size-11 cursor-pointer list-none place-items-center rounded-lg border border-tnv02-line bg-white outline-none focus-visible:ring-2 focus-visible:ring-tnv02-acc/40 [&::-webkit-details-marker]:hidden"><svg class="size-5 group-open/m:hidden" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M4 7h16M4 12h16M4 17h10"/></svg><svg class="hidden size-5 group-open/m:block" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M6 6l12 12M18 6L6 18"/></svg></summary>
<ul class="absolute top-[calc(100%+10px)] right-0 z-40 grid w-64 gap-0.5 rounded-2xl border border-tnv02-line bg-white p-2 text-[15px] font-semibold shadow-[0_24px_60px_-16px_var(--color-tnv02-shadow)] transition-[opacity,translate] duration-200 starting:-translate-y-1 starting:opacity-0 [&_a]:flex [&_a]:min-h-11 [&_a]:items-center [&_a]:rounded-lg [&_a]:px-3 [&_a:hover]:bg-tnv02-bg">
<li><a href="#">Products</a></li><li><a href="#">Solutions</a></li><li><a href="#">Pricing</a></li><li><a href="#">Resources</a></li><li><a href="#" class="text-tnv02-acc">Log in</a></li>
</ul>
</details>
</div>
</nav>
</header>
<main class="grid place-items-center px-5 py-24 text-center [&_code]:rounded [&_code]:bg-tnv02-line [&_code]:px-1.5 [&_code]:font-tnv02-mono [&_code]:text-[0.85em] [&_code]:text-tnv02-ink">
<span class="mb-6 inline-flex items-center gap-2 rounded-full bg-tnv02-acc py-1 pr-3 pl-1 text-xs font-bold text-white"><span class="grid size-5 place-items-center rounded-full bg-white/25"><span class="size-1.5 rounded-full bg-white"></span></span>Hover or Tab to any item with an arrow</span>
<h1 class="max-w-2xl text-[clamp(2.25rem,5vw,3.5rem)] leading-[1.1] font-extrabold tracking-[-0.035em] text-balance">Dropdowns that stay open when you reach for them</h1>
<p class="mt-4 max-w-lg text-base/[1.7] text-tnv02-mut text-pretty">Panels open on <code>group-hover/dd:</code> <em>and</em> <code>group-focus-within/dd:</code>, slide in with <code>translate-y</code>, and an invisible bridge stops them closing as the pointer crosses the gap.</p>
</main>
</div>@import "tailwindcss";
@theme {
--color-tnv02-bg: #f5f3ff;
--color-tnv02-bg: oklch(0.969 0.016 294);
--color-tnv02-line: #ede9fe;
--color-tnv02-line: oklch(0.943 0.029 295);
--color-tnv02-ink: #1e1b4b;
--color-tnv02-ink: oklch(0.257 0.09 281);
--color-tnv02-mut: #4b5563;
--color-tnv02-mut: oklch(0.446 0.026 257);
--color-tnv02-acc: #7c3aed;
--color-tnv02-acc: oklch(0.541 0.281 293);
--color-tnv02-acc2: #a78bfa;
--color-tnv02-acc2: oklch(0.702 0.183 294);
--color-tnv02-shadow: #7c3aed33;
--color-tnv02-shadow: oklch(0.541 0.281 293 / 0.2);
--font-tnv02-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
--font-tnv02-mono: 'JetBrains Mono', ui-monospace, monospace;
}
.tnv-02 {
width: 100%;
min-height: 100svh;
}@import "tailwindcss";
@theme {
--color-tnv02-bg: #f5f3ff;
--color-tnv02-bg: oklch(0.969 0.016 294);
--color-tnv02-line: #ede9fe;
--color-tnv02-line: oklch(0.943 0.029 295);
--color-tnv02-ink: #1e1b4b;
--color-tnv02-ink: oklch(0.257 0.09 281);
--color-tnv02-mut: #4b5563;
--color-tnv02-mut: oklch(0.446 0.026 257);
--color-tnv02-acc: #7c3aed;
--color-tnv02-acc: oklch(0.541 0.281 293);
--color-tnv02-acc2: #a78bfa;
--color-tnv02-acc2: oklch(0.702 0.183 294);
--color-tnv02-shadow: #7c3aed33;
--color-tnv02-shadow: oklch(0.541 0.281 293 / 0.2);
--font-tnv02-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
--font-tnv02-mono: 'JetBrains Mono', ui-monospace, monospace;
}
.tnv-02 {
width: 100%;
min-height: 100svh;
}Setup — do this once per project
Skip this if your project already runs Tailwind v4.
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>Compiles in the browser — perfect for a CodePen or a quick test, not for production.
npm install tailwindcss @tailwindcss/vite
npm install tailwindcss @tailwindcss/vite// vite.config.js ("type": "module" in package.json)
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [tailwindcss()],
})// vite.config.js ("type": "module" in package.json)
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [tailwindcss()],
})Any v4 setup works — Vite, PostCSS or the CLI. Nothing in this demo is bundler-specific.
@import "tailwindcss";
@theme {
--color-tnv02-bg: #f5f3ff;
--color-tnv02-bg: oklch(0.969 0.016 294);
--color-tnv02-line: #ede9fe;
--color-tnv02-line: oklch(0.943 0.029 295);
--color-tnv02-ink: #1e1b4b;
--color-tnv02-ink: oklch(0.257 0.09 281);
--color-tnv02-mut: #4b5563;
--color-tnv02-mut: oklch(0.446 0.026 257);
--color-tnv02-acc: #7c3aed;
--color-tnv02-acc: oklch(0.541 0.281 293);
--color-tnv02-acc2: #a78bfa;
--color-tnv02-acc2: oklch(0.702 0.183 294);
--color-tnv02-shadow: #7c3aed33;
--color-tnv02-shadow: oklch(0.541 0.281 293 / 0.2);
--font-tnv02-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
--font-tnv02-mono: 'JetBrains Mono', ui-monospace, monospace;
}
.tnv-02 {
width: 100%;
min-height: 100svh;
}@import "tailwindcss";
@theme {
--color-tnv02-bg: #f5f3ff;
--color-tnv02-bg: oklch(0.969 0.016 294);
--color-tnv02-line: #ede9fe;
--color-tnv02-line: oklch(0.943 0.029 295);
--color-tnv02-ink: #1e1b4b;
--color-tnv02-ink: oklch(0.257 0.09 281);
--color-tnv02-mut: #4b5563;
--color-tnv02-mut: oklch(0.446 0.026 257);
--color-tnv02-acc: #7c3aed;
--color-tnv02-acc: oklch(0.541 0.281 293);
--color-tnv02-acc2: #a78bfa;
--color-tnv02-acc2: oklch(0.702 0.183 294);
--color-tnv02-shadow: #7c3aed33;
--color-tnv02-shadow: oklch(0.541 0.281 293 / 0.2);
--font-tnv02-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
--font-tnv02-mono: 'JetBrains Mono', ui-monospace, monospace;
}
.tnv-02 {
width: 100%;
min-height: 100svh;
}<link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap">What changed in the port
Which parts became utilities, which stayed CSS, and why.
.links > li:hover .dropdown, .links > li:focus-within .dropdownbecamegroup-hover/dd:+group-focus-within/dd:on the panel itself.- The repeated row styles on the compact menus collapsed into parent-level arbitrary variants (
[&_a]:min-h-11,[&_a:hover]:bg-…) — one class list for every row. - Bug fix from the CSS original: the panel sat 8px below its trigger with nothing bridging the gap, so moving the pointer down often closed the menu. A
before:hover bridge fixes it. - UI upgrade: hidden panels are now
invisible(they were onlyopacity:0, leaving every link tabbable); triggers are real buttons; rows are 44px; icon tiles fill on hover; a divider<div>inside a<ul>(invalid HTML) became<li role="separator">.
Here's a working CSS demo from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Tailwind CSS Dropdown Menu — Hover & Keyboard Accessible
Source: https://codefronts.com/navigation/tailwind-css-navigation-menus/tailwind-css-dropdown-menu-hover-keyboard-accessible/
A product-site navbar with rich dropdowns — a two-column panel with icon tiles, a compact list and a resources menu — that open on group-hover/dd: and, just as importantly, on group-focus-within/dd: so keyboard users get the same menu. An invisible hover bridge fixes the classic ‘menu closes when you move to it’ bug. Zero JavaScript.
## HTML
```html
<div class="tnv-02 min-h-svh w-full bg-tnv02-bg bg-[radial-gradient(80%_60%_at_50%_0%,white,transparent)] font-tnv02-sans text-tnv02-ink antialiased selection:bg-tnv02-acc selection:text-white">
<header class="sticky top-0 z-30 border-b border-tnv02-line bg-white/90 shadow-[0_2px_20px_-8px_var(--color-tnv02-shadow)] backdrop-blur-md">
<nav aria-label="Main" class="mx-auto flex h-[68px] max-w-6xl items-center justify-between gap-6 px-5 sm:px-10">
<a href="#" class="flex items-center gap-2.5 text-xl font-bold tracking-[-0.03em]">
<span class="grid size-8 place-items-center rounded-lg bg-linear-135 from-tnv02-acc to-tnv02-acc2 shadow-[0_4px_12px_-4px_var(--color-tnv02-acc)]"><svg class="size-[18px] fill-white" viewBox="0 0 24 24" aria-hidden="true"><path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"/></svg></span>Vertex
</a>
<ul class="hidden items-center gap-0.5 md:flex">
<li class="group/dd relative">
<button type="button" aria-haspopup="true" class="flex h-11 items-center gap-1.5 rounded-lg px-3.5 text-sm font-semibold text-tnv02-mut transition-colors group-hover/dd:bg-tnv02-bg group-hover/dd:text-tnv02-ink group-focus-within/dd:bg-tnv02-bg group-focus-within/dd:text-tnv02-ink focus-visible:outline-2 focus-visible:outline-tnv02-acc">Products<svg class="size-3.5 opacity-60 transition-transform duration-200 group-hover/dd:rotate-180 group-focus-within/dd:rotate-180" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M6 9l6 6 6-6"/></svg></button>
<div class="invisible absolute top-full left-1/2 z-40 mt-2.5 grid w-[30rem] -translate-x-1/2 translate-y-1.5 grid-cols-2 gap-1 rounded-2xl border border-tnv02-line bg-white p-2 opacity-0 shadow-[0_24px_60px_-16px_var(--color-tnv02-shadow)] transition-[opacity,translate,visibility] duration-200 ease-[cubic-bezier(.16,1,.3,1)] before:absolute before:inset-x-0 before:-top-3 before:h-3 before:content-[''] group-hover/dd:visible group-hover/dd:translate-y-0 group-hover/dd:opacity-100 group-focus-within/dd:visible group-focus-within/dd:translate-y-0 group-focus-within/dd:opacity-100 motion-reduce:transition-none">
<a href="#" class="group/it flex items-center gap-3 rounded-xl p-3 outline-none transition-colors hover:bg-tnv02-bg focus-visible:bg-tnv02-bg focus-visible:ring-2 focus-visible:ring-tnv02-acc/40"><span class="grid size-10 flex-none place-items-center rounded-lg bg-tnv02-bg text-tnv02-acc transition-colors group-hover/it:bg-tnv02-acc group-hover/it:text-white"><svg class="size-[18px]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><rect x="3" y="3" width="7" height="7" rx="1.5"/><rect x="14" y="3" width="7" height="7" rx="1.5"/><rect x="3" y="14" width="7" height="7" rx="1.5"/><rect x="14" y="14" width="7" height="7" rx="1.5"/></svg></span><span class="grid text-sm font-semibold">Dashboard<span class="text-xs font-medium text-tnv02-mut">Analytics & insights</span></span></a>
<a href="#" class="group/it flex items-center gap-3 rounded-xl p-3 outline-none transition-colors hover:bg-tnv02-bg focus-visible:bg-tnv02-bg focus-visible:ring-2 focus-visible:ring-tnv02-acc/40"><span class="grid size-10 flex-none place-items-center rounded-lg bg-tnv02-bg text-tnv02-acc transition-colors group-hover/it:bg-tnv02-acc group-hover/it:text-white"><svg class="size-[18px]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M22 12h-4l-3 9L9 3l-3 9H2"/></svg></span><span class="grid text-sm font-semibold">Monitoring<span class="text-xs font-medium text-tnv02-mut">Real-time metrics</span></span></a>
<a href="#" class="group/it flex items-center gap-3 rounded-xl p-3 outline-none transition-colors hover:bg-tnv02-bg focus-visible:bg-tnv02-bg focus-visible:ring-2 focus-visible:ring-tnv02-acc/40"><span class="grid size-10 flex-none place-items-center rounded-lg bg-tnv02-bg text-tnv02-acc transition-colors group-hover/it:bg-tnv02-acc group-hover/it:text-white"><svg class="size-[18px]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M17 21v-2a4 4 0 00-4-4H5a4 4 0 00-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 00-3-3.87M16 3.13a4 4 0 010 7.75"/></svg></span><span class="grid text-sm font-semibold">Teams<span class="text-xs font-medium text-tnv02-mut">Collaboration tools</span></span></a>
<a href="#" class="group/it flex items-center gap-3 rounded-xl p-3 outline-none transition-colors hover:bg-tnv02-bg focus-visible:bg-tnv02-bg focus-visible:ring-2 focus-visible:ring-tnv02-acc/40"><span class="grid size-10 flex-none place-items-center rounded-lg bg-tnv02-bg text-tnv02-acc transition-colors group-hover/it:bg-tnv02-acc group-hover/it:text-white"><svg class="size-[18px]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z"/></svg></span><span class="grid text-sm font-semibold"><span class="flex items-center gap-1.5">Automation<span class="rounded-full bg-tnv02-acc/10 px-1.5 py-px text-[10px] font-bold tracking-wide text-tnv02-acc uppercase">New</span></span><span class="text-xs font-medium text-tnv02-mut">Workflow builder</span></span></a>
<a href="#" class="col-span-2 mt-1 flex min-h-11 items-center justify-between rounded-xl bg-linear-135 from-tnv02-bg to-tnv02-line px-4 py-3 text-[13px] font-bold text-tnv02-acc transition hover:brightness-[0.97] focus-visible:outline-2 focus-visible:outline-tnv02-acc">Explore all products<svg class="size-4 transition-transform group-hover/dd:translate-x-0.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M5 12h14M12 5l7 7-7 7"/></svg></a>
</div>
</li>
<li class="group/dd relative">
<button type="button" aria-haspopup="true" class="flex h-11 items-center gap-1.5 rounded-lg px-3.5 text-sm font-semibold text-tnv02-mut transition-colors group-hover/dd:bg-tnv02-bg group-hover/dd:text-tnv02-ink group-focus-within/dd:bg-tnv02-bg group-focus-within/dd:text-tnv02-ink focus-visible:outline-2 focus-visible:outline-tnv02-acc">Solutions<svg class="size-3.5 opacity-60 transition-transform duration-200 group-hover/dd:rotate-180 group-focus-within/dd:rotate-180" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M6 9l6 6 6-6"/></svg></button>
<ul class="invisible absolute top-full left-1/2 z-40 mt-2.5 grid w-56 -translate-x-1/2 translate-y-1.5 gap-0.5 rounded-2xl border border-tnv02-line bg-white p-2 text-sm font-semibold text-tnv02-mut opacity-0 shadow-[0_24px_60px_-16px_var(--color-tnv02-shadow)] transition-[opacity,translate,visibility] duration-200 ease-[cubic-bezier(.16,1,.3,1)] before:absolute before:inset-x-0 before:-top-3 before:h-3 before:content-[''] group-hover/dd:visible group-hover/dd:translate-y-0 group-hover/dd:opacity-100 group-focus-within/dd:visible group-focus-within/dd:translate-y-0 group-focus-within/dd:opacity-100 motion-reduce:transition-none [&_a]:flex [&_a]:min-h-11 [&_a]:items-center [&_a]:rounded-lg [&_a]:px-3 [&_a]:outline-none [&_a:focus-visible]:bg-tnv02-bg [&_a:focus-visible]:text-tnv02-ink [&_a:hover]:bg-tnv02-bg [&_a:hover]:text-tnv02-ink">
<li><a href="#">Enterprise</a></li>
<li><a href="#">Startups</a></li>
<li><a href="#">Agencies</a></li>
<li role="separator" class="mx-2 my-1 h-px bg-tnv02-line"></li>
<li><a href="#">Case studies</a></li>
</ul>
</li>
<li><a href="#" class="flex h-11 items-center rounded-lg px-3.5 text-sm font-semibold text-tnv02-mut transition-colors hover:bg-tnv02-bg hover:text-tnv02-ink focus-visible:outline-2 focus-visible:outline-tnv02-acc">Pricing</a></li>
<li class="group/dd relative">
<button type="button" aria-haspopup="true" class="flex h-11 items-center gap-1.5 rounded-lg px-3.5 text-sm font-semibold text-tnv02-mut transition-colors group-hover/dd:bg-tnv02-bg group-hover/dd:text-tnv02-ink group-focus-within/dd:bg-tnv02-bg group-focus-within/dd:text-tnv02-ink focus-visible:outline-2 focus-visible:outline-tnv02-acc">Resources<svg class="size-3.5 opacity-60 transition-transform duration-200 group-hover/dd:rotate-180 group-focus-within/dd:rotate-180" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M6 9l6 6 6-6"/></svg></button>
<ul class="invisible absolute top-full left-1/2 z-40 mt-2.5 grid w-56 -translate-x-1/2 translate-y-1.5 gap-0.5 rounded-2xl border border-tnv02-line bg-white p-2 text-sm font-semibold text-tnv02-mut opacity-0 shadow-[0_24px_60px_-16px_var(--color-tnv02-shadow)] transition-[opacity,translate,visibility] duration-200 ease-[cubic-bezier(.16,1,.3,1)] before:absolute before:inset-x-0 before:-top-3 before:h-3 before:content-[''] group-hover/dd:visible group-hover/dd:translate-y-0 group-hover/dd:opacity-100 group-focus-within/dd:visible group-focus-within/dd:translate-y-0 group-focus-within/dd:opacity-100 motion-reduce:transition-none [&_a]:flex [&_a]:min-h-11 [&_a]:items-center [&_a]:justify-between [&_a]:rounded-lg [&_a]:px-3 [&_a]:outline-none [&_a:focus-visible]:bg-tnv02-bg [&_a:focus-visible]:text-tnv02-ink [&_a:hover]:bg-tnv02-bg [&_a:hover]:text-tnv02-ink">
<li><a href="#">Documentation<kbd class="font-tnv02-mono text-[11px] font-medium text-tnv02-mut">D</kbd></a></li>
<li><a href="#">Blog</a></li>
<li><a href="#">Community</a></li>
</ul>
</li>
</ul>
<div class="flex items-center gap-2.5">
<a href="#" class="hidden h-10 items-center rounded-lg border-[1.5px] border-tnv02-line px-4 text-sm font-semibold text-tnv02-acc transition hover:border-tnv02-acc2 hover:bg-tnv02-bg focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tnv02-acc sm:inline-flex">Log in</a>
<a href="#" class="inline-flex h-10 items-center rounded-lg bg-tnv02-acc px-4 text-sm font-semibold text-white shadow-[0_6px_16px_-6px_var(--color-tnv02-acc)] transition hover:brightness-110 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tnv02-acc">Start free</a>
<details class="group/m relative md:hidden">
<summary aria-label="Menu" class="grid size-11 cursor-pointer list-none place-items-center rounded-lg border border-tnv02-line bg-white outline-none focus-visible:ring-2 focus-visible:ring-tnv02-acc/40 [&::-webkit-details-marker]:hidden"><svg class="size-5 group-open/m:hidden" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M4 7h16M4 12h16M4 17h10"/></svg><svg class="hidden size-5 group-open/m:block" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M6 6l12 12M18 6L6 18"/></svg></summary>
<ul class="absolute top-[calc(100%+10px)] right-0 z-40 grid w-64 gap-0.5 rounded-2xl border border-tnv02-line bg-white p-2 text-[15px] font-semibold shadow-[0_24px_60px_-16px_var(--color-tnv02-shadow)] transition-[opacity,translate] duration-200 starting:-translate-y-1 starting:opacity-0 [&_a]:flex [&_a]:min-h-11 [&_a]:items-center [&_a]:rounded-lg [&_a]:px-3 [&_a:hover]:bg-tnv02-bg">
<li><a href="#">Products</a></li><li><a href="#">Solutions</a></li><li><a href="#">Pricing</a></li><li><a href="#">Resources</a></li><li><a href="#" class="text-tnv02-acc">Log in</a></li>
</ul>
</details>
</div>
</nav>
</header>
<main class="grid place-items-center px-5 py-24 text-center [&_code]:rounded [&_code]:bg-tnv02-line [&_code]:px-1.5 [&_code]:font-tnv02-mono [&_code]:text-[0.85em] [&_code]:text-tnv02-ink">
<span class="mb-6 inline-flex items-center gap-2 rounded-full bg-tnv02-acc py-1 pr-3 pl-1 text-xs font-bold text-white"><span class="grid size-5 place-items-center rounded-full bg-white/25"><span class="size-1.5 rounded-full bg-white"></span></span>Hover or Tab to any item with an arrow</span>
<h1 class="max-w-2xl text-[clamp(2.25rem,5vw,3.5rem)] leading-[1.1] font-extrabold tracking-[-0.035em] text-balance">Dropdowns that stay open when you reach for them</h1>
<p class="mt-4 max-w-lg text-base/[1.7] text-tnv02-mut text-pretty">Panels open on <code>group-hover/dd:</code> <em>and</em> <code>group-focus-within/dd:</code>, slide in with <code>translate-y</code>, and an invisible bridge stops them closing as the pointer crosses the gap.</p>
</main>
</div>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tnv02-bg: #f5f3ff;
--color-tnv02-bg: oklch(0.969 0.016 294);
--color-tnv02-line: #ede9fe;
--color-tnv02-line: oklch(0.943 0.029 295);
--color-tnv02-ink: #1e1b4b;
--color-tnv02-ink: oklch(0.257 0.09 281);
--color-tnv02-mut: #4b5563;
--color-tnv02-mut: oklch(0.446 0.026 257);
--color-tnv02-acc: #7c3aed;
--color-tnv02-acc: oklch(0.541 0.281 293);
--color-tnv02-acc2: #a78bfa;
--color-tnv02-acc2: oklch(0.702 0.183 294);
--color-tnv02-shadow: #7c3aed33;
--color-tnv02-shadow: oklch(0.541 0.281 293 / 0.2);
--font-tnv02-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
--font-tnv02-mono: 'JetBrains Mono', ui-monospace, monospace;
}
.tnv-02 {
width: 100%;
min-height: 100svh;
}
```Here's a working CSS demo from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Tailwind CSS Dropdown Menu — Hover & Keyboard Accessible
Source: https://codefronts.com/navigation/tailwind-css-navigation-menus/tailwind-css-dropdown-menu-hover-keyboard-accessible/
A product-site navbar with rich dropdowns — a two-column panel with icon tiles, a compact list and a resources menu — that open on group-hover/dd: and, just as importantly, on group-focus-within/dd: so keyboard users get the same menu. An invisible hover bridge fixes the classic ‘menu closes when you move to it’ bug. Zero JavaScript.
## HTML
```html
<div class="tnv-02 min-h-svh w-full bg-tnv02-bg bg-[radial-gradient(80%_60%_at_50%_0%,white,transparent)] font-tnv02-sans text-tnv02-ink antialiased selection:bg-tnv02-acc selection:text-white">
<header class="sticky top-0 z-30 border-b border-tnv02-line bg-white/90 shadow-[0_2px_20px_-8px_var(--color-tnv02-shadow)] backdrop-blur-md">
<nav aria-label="Main" class="mx-auto flex h-[68px] max-w-6xl items-center justify-between gap-6 px-5 sm:px-10">
<a href="#" class="flex items-center gap-2.5 text-xl font-bold tracking-[-0.03em]">
<span class="grid size-8 place-items-center rounded-lg bg-linear-135 from-tnv02-acc to-tnv02-acc2 shadow-[0_4px_12px_-4px_var(--color-tnv02-acc)]"><svg class="size-[18px] fill-white" viewBox="0 0 24 24" aria-hidden="true"><path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"/></svg></span>Vertex
</a>
<ul class="hidden items-center gap-0.5 md:flex">
<li class="group/dd relative">
<button type="button" aria-haspopup="true" class="flex h-11 items-center gap-1.5 rounded-lg px-3.5 text-sm font-semibold text-tnv02-mut transition-colors group-hover/dd:bg-tnv02-bg group-hover/dd:text-tnv02-ink group-focus-within/dd:bg-tnv02-bg group-focus-within/dd:text-tnv02-ink focus-visible:outline-2 focus-visible:outline-tnv02-acc">Products<svg class="size-3.5 opacity-60 transition-transform duration-200 group-hover/dd:rotate-180 group-focus-within/dd:rotate-180" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M6 9l6 6 6-6"/></svg></button>
<div class="invisible absolute top-full left-1/2 z-40 mt-2.5 grid w-[30rem] -translate-x-1/2 translate-y-1.5 grid-cols-2 gap-1 rounded-2xl border border-tnv02-line bg-white p-2 opacity-0 shadow-[0_24px_60px_-16px_var(--color-tnv02-shadow)] transition-[opacity,translate,visibility] duration-200 ease-[cubic-bezier(.16,1,.3,1)] before:absolute before:inset-x-0 before:-top-3 before:h-3 before:content-[''] group-hover/dd:visible group-hover/dd:translate-y-0 group-hover/dd:opacity-100 group-focus-within/dd:visible group-focus-within/dd:translate-y-0 group-focus-within/dd:opacity-100 motion-reduce:transition-none">
<a href="#" class="group/it flex items-center gap-3 rounded-xl p-3 outline-none transition-colors hover:bg-tnv02-bg focus-visible:bg-tnv02-bg focus-visible:ring-2 focus-visible:ring-tnv02-acc/40"><span class="grid size-10 flex-none place-items-center rounded-lg bg-tnv02-bg text-tnv02-acc transition-colors group-hover/it:bg-tnv02-acc group-hover/it:text-white"><svg class="size-[18px]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><rect x="3" y="3" width="7" height="7" rx="1.5"/><rect x="14" y="3" width="7" height="7" rx="1.5"/><rect x="3" y="14" width="7" height="7" rx="1.5"/><rect x="14" y="14" width="7" height="7" rx="1.5"/></svg></span><span class="grid text-sm font-semibold">Dashboard<span class="text-xs font-medium text-tnv02-mut">Analytics & insights</span></span></a>
<a href="#" class="group/it flex items-center gap-3 rounded-xl p-3 outline-none transition-colors hover:bg-tnv02-bg focus-visible:bg-tnv02-bg focus-visible:ring-2 focus-visible:ring-tnv02-acc/40"><span class="grid size-10 flex-none place-items-center rounded-lg bg-tnv02-bg text-tnv02-acc transition-colors group-hover/it:bg-tnv02-acc group-hover/it:text-white"><svg class="size-[18px]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M22 12h-4l-3 9L9 3l-3 9H2"/></svg></span><span class="grid text-sm font-semibold">Monitoring<span class="text-xs font-medium text-tnv02-mut">Real-time metrics</span></span></a>
<a href="#" class="group/it flex items-center gap-3 rounded-xl p-3 outline-none transition-colors hover:bg-tnv02-bg focus-visible:bg-tnv02-bg focus-visible:ring-2 focus-visible:ring-tnv02-acc/40"><span class="grid size-10 flex-none place-items-center rounded-lg bg-tnv02-bg text-tnv02-acc transition-colors group-hover/it:bg-tnv02-acc group-hover/it:text-white"><svg class="size-[18px]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M17 21v-2a4 4 0 00-4-4H5a4 4 0 00-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 00-3-3.87M16 3.13a4 4 0 010 7.75"/></svg></span><span class="grid text-sm font-semibold">Teams<span class="text-xs font-medium text-tnv02-mut">Collaboration tools</span></span></a>
<a href="#" class="group/it flex items-center gap-3 rounded-xl p-3 outline-none transition-colors hover:bg-tnv02-bg focus-visible:bg-tnv02-bg focus-visible:ring-2 focus-visible:ring-tnv02-acc/40"><span class="grid size-10 flex-none place-items-center rounded-lg bg-tnv02-bg text-tnv02-acc transition-colors group-hover/it:bg-tnv02-acc group-hover/it:text-white"><svg class="size-[18px]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z"/></svg></span><span class="grid text-sm font-semibold"><span class="flex items-center gap-1.5">Automation<span class="rounded-full bg-tnv02-acc/10 px-1.5 py-px text-[10px] font-bold tracking-wide text-tnv02-acc uppercase">New</span></span><span class="text-xs font-medium text-tnv02-mut">Workflow builder</span></span></a>
<a href="#" class="col-span-2 mt-1 flex min-h-11 items-center justify-between rounded-xl bg-linear-135 from-tnv02-bg to-tnv02-line px-4 py-3 text-[13px] font-bold text-tnv02-acc transition hover:brightness-[0.97] focus-visible:outline-2 focus-visible:outline-tnv02-acc">Explore all products<svg class="size-4 transition-transform group-hover/dd:translate-x-0.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M5 12h14M12 5l7 7-7 7"/></svg></a>
</div>
</li>
<li class="group/dd relative">
<button type="button" aria-haspopup="true" class="flex h-11 items-center gap-1.5 rounded-lg px-3.5 text-sm font-semibold text-tnv02-mut transition-colors group-hover/dd:bg-tnv02-bg group-hover/dd:text-tnv02-ink group-focus-within/dd:bg-tnv02-bg group-focus-within/dd:text-tnv02-ink focus-visible:outline-2 focus-visible:outline-tnv02-acc">Solutions<svg class="size-3.5 opacity-60 transition-transform duration-200 group-hover/dd:rotate-180 group-focus-within/dd:rotate-180" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M6 9l6 6 6-6"/></svg></button>
<ul class="invisible absolute top-full left-1/2 z-40 mt-2.5 grid w-56 -translate-x-1/2 translate-y-1.5 gap-0.5 rounded-2xl border border-tnv02-line bg-white p-2 text-sm font-semibold text-tnv02-mut opacity-0 shadow-[0_24px_60px_-16px_var(--color-tnv02-shadow)] transition-[opacity,translate,visibility] duration-200 ease-[cubic-bezier(.16,1,.3,1)] before:absolute before:inset-x-0 before:-top-3 before:h-3 before:content-[''] group-hover/dd:visible group-hover/dd:translate-y-0 group-hover/dd:opacity-100 group-focus-within/dd:visible group-focus-within/dd:translate-y-0 group-focus-within/dd:opacity-100 motion-reduce:transition-none [&_a]:flex [&_a]:min-h-11 [&_a]:items-center [&_a]:rounded-lg [&_a]:px-3 [&_a]:outline-none [&_a:focus-visible]:bg-tnv02-bg [&_a:focus-visible]:text-tnv02-ink [&_a:hover]:bg-tnv02-bg [&_a:hover]:text-tnv02-ink">
<li><a href="#">Enterprise</a></li>
<li><a href="#">Startups</a></li>
<li><a href="#">Agencies</a></li>
<li role="separator" class="mx-2 my-1 h-px bg-tnv02-line"></li>
<li><a href="#">Case studies</a></li>
</ul>
</li>
<li><a href="#" class="flex h-11 items-center rounded-lg px-3.5 text-sm font-semibold text-tnv02-mut transition-colors hover:bg-tnv02-bg hover:text-tnv02-ink focus-visible:outline-2 focus-visible:outline-tnv02-acc">Pricing</a></li>
<li class="group/dd relative">
<button type="button" aria-haspopup="true" class="flex h-11 items-center gap-1.5 rounded-lg px-3.5 text-sm font-semibold text-tnv02-mut transition-colors group-hover/dd:bg-tnv02-bg group-hover/dd:text-tnv02-ink group-focus-within/dd:bg-tnv02-bg group-focus-within/dd:text-tnv02-ink focus-visible:outline-2 focus-visible:outline-tnv02-acc">Resources<svg class="size-3.5 opacity-60 transition-transform duration-200 group-hover/dd:rotate-180 group-focus-within/dd:rotate-180" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M6 9l6 6 6-6"/></svg></button>
<ul class="invisible absolute top-full left-1/2 z-40 mt-2.5 grid w-56 -translate-x-1/2 translate-y-1.5 gap-0.5 rounded-2xl border border-tnv02-line bg-white p-2 text-sm font-semibold text-tnv02-mut opacity-0 shadow-[0_24px_60px_-16px_var(--color-tnv02-shadow)] transition-[opacity,translate,visibility] duration-200 ease-[cubic-bezier(.16,1,.3,1)] before:absolute before:inset-x-0 before:-top-3 before:h-3 before:content-[''] group-hover/dd:visible group-hover/dd:translate-y-0 group-hover/dd:opacity-100 group-focus-within/dd:visible group-focus-within/dd:translate-y-0 group-focus-within/dd:opacity-100 motion-reduce:transition-none [&_a]:flex [&_a]:min-h-11 [&_a]:items-center [&_a]:justify-between [&_a]:rounded-lg [&_a]:px-3 [&_a]:outline-none [&_a:focus-visible]:bg-tnv02-bg [&_a:focus-visible]:text-tnv02-ink [&_a:hover]:bg-tnv02-bg [&_a:hover]:text-tnv02-ink">
<li><a href="#">Documentation<kbd class="font-tnv02-mono text-[11px] font-medium text-tnv02-mut">D</kbd></a></li>
<li><a href="#">Blog</a></li>
<li><a href="#">Community</a></li>
</ul>
</li>
</ul>
<div class="flex items-center gap-2.5">
<a href="#" class="hidden h-10 items-center rounded-lg border-[1.5px] border-tnv02-line px-4 text-sm font-semibold text-tnv02-acc transition hover:border-tnv02-acc2 hover:bg-tnv02-bg focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tnv02-acc sm:inline-flex">Log in</a>
<a href="#" class="inline-flex h-10 items-center rounded-lg bg-tnv02-acc px-4 text-sm font-semibold text-white shadow-[0_6px_16px_-6px_var(--color-tnv02-acc)] transition hover:brightness-110 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tnv02-acc">Start free</a>
<details class="group/m relative md:hidden">
<summary aria-label="Menu" class="grid size-11 cursor-pointer list-none place-items-center rounded-lg border border-tnv02-line bg-white outline-none focus-visible:ring-2 focus-visible:ring-tnv02-acc/40 [&::-webkit-details-marker]:hidden"><svg class="size-5 group-open/m:hidden" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M4 7h16M4 12h16M4 17h10"/></svg><svg class="hidden size-5 group-open/m:block" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M6 6l12 12M18 6L6 18"/></svg></summary>
<ul class="absolute top-[calc(100%+10px)] right-0 z-40 grid w-64 gap-0.5 rounded-2xl border border-tnv02-line bg-white p-2 text-[15px] font-semibold shadow-[0_24px_60px_-16px_var(--color-tnv02-shadow)] transition-[opacity,translate] duration-200 starting:-translate-y-1 starting:opacity-0 [&_a]:flex [&_a]:min-h-11 [&_a]:items-center [&_a]:rounded-lg [&_a]:px-3 [&_a:hover]:bg-tnv02-bg">
<li><a href="#">Products</a></li><li><a href="#">Solutions</a></li><li><a href="#">Pricing</a></li><li><a href="#">Resources</a></li><li><a href="#" class="text-tnv02-acc">Log in</a></li>
</ul>
</details>
</div>
</nav>
</header>
<main class="grid place-items-center px-5 py-24 text-center [&_code]:rounded [&_code]:bg-tnv02-line [&_code]:px-1.5 [&_code]:font-tnv02-mono [&_code]:text-[0.85em] [&_code]:text-tnv02-ink">
<span class="mb-6 inline-flex items-center gap-2 rounded-full bg-tnv02-acc py-1 pr-3 pl-1 text-xs font-bold text-white"><span class="grid size-5 place-items-center rounded-full bg-white/25"><span class="size-1.5 rounded-full bg-white"></span></span>Hover or Tab to any item with an arrow</span>
<h1 class="max-w-2xl text-[clamp(2.25rem,5vw,3.5rem)] leading-[1.1] font-extrabold tracking-[-0.035em] text-balance">Dropdowns that stay open when you reach for them</h1>
<p class="mt-4 max-w-lg text-base/[1.7] text-tnv02-mut text-pretty">Panels open on <code>group-hover/dd:</code> <em>and</em> <code>group-focus-within/dd:</code>, slide in with <code>translate-y</code>, and an invisible bridge stops them closing as the pointer crosses the gap.</p>
</main>
</div>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tnv02-bg: #f5f3ff;
--color-tnv02-bg: oklch(0.969 0.016 294);
--color-tnv02-line: #ede9fe;
--color-tnv02-line: oklch(0.943 0.029 295);
--color-tnv02-ink: #1e1b4b;
--color-tnv02-ink: oklch(0.257 0.09 281);
--color-tnv02-mut: #4b5563;
--color-tnv02-mut: oklch(0.446 0.026 257);
--color-tnv02-acc: #7c3aed;
--color-tnv02-acc: oklch(0.541 0.281 293);
--color-tnv02-acc2: #a78bfa;
--color-tnv02-acc2: oklch(0.702 0.183 294);
--color-tnv02-shadow: #7c3aed33;
--color-tnv02-shadow: oklch(0.541 0.281 293 / 0.2);
--font-tnv02-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
--font-tnv02-mono: 'JetBrains Mono', ui-monospace, monospace;
}
.tnv-02 {
width: 100%;
min-height: 100svh;
}
```How this works
Named groups keep nested hovers apart. The menu item is group/dd, each row inside is group/it, so the caret rotates for the menu while the tile fills only for the hovered row.
<li class="group/dd relative">
<button>Products <svg class="group-hover/dd:rotate-180"></button>
<div class="invisible opacity-0 translate-y-1.5
group-hover/dd:visible group-hover/dd:opacity-100 group-hover/dd:translate-y-0
group-focus-within/dd:visible ...">The bridge. The panel sits 10px below its trigger. Crossing that gap used to end :hover and slam the panel shut. A transparent before: strip spanning the gap keeps the pointer ‘inside’ the item.
Make it yours
- Three columns:
w-[42rem] grid-cols-3on the wide panel. - Left-aligned panels: replace
left-1/2 -translate-x-1/2withleft-0. - Slower, softer entrance:
duration-300 ease-out.
Gotchas — read before shipping
- Pure-CSS dropdowns cannot set
aria-expanded; for production, add a few lines of JS to toggle it on the trigger button. invisibleis required, not cosmetic:opacity-0alone leaves every hidden link tabbable and clickable.- Touch devices open the menu on first tap via
:focus-within; keep the trigger a<button>, not a link, so that tap doesn't navigate.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
:focus-within is universal in this range; the floor is Tailwind v4's own sheet.