12 / 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 Multi-Level Accordion Sidebar Menu
A documentation-site sidebar with nested, animated sections. The checkbox hack is gone: every section is a native <details>, so it announces expanded/collapsed, works with Enter and Space, and opens for find-in-page. Height animates to auto through ::details-content with interpolate-size; chevrons turn with group-open/l1:. Zero JavaScript.
Nucleo: 44,000+ SVG icons in five families · All Icons Bundle $149
Nucleo · Affiliate link
The code
<div class="tnv-12 flex min-h-svh w-full flex-col bg-tnv12-bg font-tnv12-sans text-tnv12-ink antialiased selection:bg-tnv12-acc selection:text-white md:flex-row">
<aside class="flex w-full flex-none flex-col border-b border-tnv12-line bg-white md:sticky md:top-0 md:h-svh md:w-[17rem] md:border-r md:border-b-0">
<div class="flex items-center gap-2.5 border-b border-tnv12-line px-4 py-4">
<span class="grid size-8 place-items-center rounded-lg bg-tnv12-acc"><svg class="size-4" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" aria-hidden="true"><path d="M2 3h6a4 4 0 014 4v14a3 3 0 00-3-3H2zM22 3h-6a4 4 0 00-4 4v14a3 3 0 013-3h7z"/></svg></span>
<span class="font-semibold"><span class="text-tnv12-acc-ink">Dev</span>Docs</span>
<span class="ml-auto rounded-md bg-tnv12-soft px-1.5 py-0.5 font-tnv12-mono text-[11px] font-medium text-tnv12-acc-ink">v4.2</span>
</div>
<div class="border-b border-tnv12-line p-3">
<button type="button" class="flex h-10 w-full items-center gap-2 rounded-lg border border-tnv12-line bg-tnv12-bg px-3 text-left text-[13px] text-tnv12-mut transition-colors hover:border-slate-300"><svg class="size-4 flex-none" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><circle cx="11" cy="11" r="8"/><path d="M21 21l-4.35-4.35"/></svg>Search docs<kbd class="ml-auto rounded border border-tnv12-line bg-white px-1.5 font-tnv12-mono text-[10px]">⌘K</kbd></button>
</div>
<nav aria-label="Documentation" class="flex-1 overflow-y-auto p-2 text-sm font-medium text-tnv12-mut [&_summary]:flex [&_summary]:min-h-10 [&_summary]:cursor-pointer [&_summary]:list-none [&_summary]:items-center [&_summary]:gap-2.5 [&_summary]:rounded-lg [&_summary]:px-2.5 [&_summary]:transition-colors [&_summary]:select-none [&_summary:hover]:bg-tnv12-bg [&_summary:hover]:text-tnv12-ink [&_summary:focus-visible]:outline-2 [&_summary:focus-visible]:outline-tnv12-acc [&_summary::-webkit-details-marker]:hidden [&_a]:flex [&_a]:min-h-10 [&_a]:items-center [&_a]:gap-2.5 [&_a]:rounded-lg [&_a]:px-2.5 [&_a]:transition-colors [&_a:hover]:bg-tnv12-bg [&_a:hover]:text-tnv12-ink [&_a:focus-visible]:outline-2 [&_a:focus-visible]:outline-tnv12-acc [&_svg]:size-4 [&_svg]:flex-none">
<ul class="space-y-0.5">
<li><a href="#"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M3 9l9-7 9 7v11a2 2 0 01-2 2H5a2 2 0 01-2-2z"/></svg>Introduction</a></li>
<li><details open class="group/l1">
<summary><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M22 19a2 2 0 01-2 2H4a2 2 0 01-2-2V5a2 2 0 012-2h5l2 3h9a2 2 0 012 2z"/></svg>Getting Started<svg class="ml-auto size-3.5! opacity-60 transition-transform duration-200 group-open/l1:rotate-90" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M9 18l6-6-6-6"/></svg></summary>
<ul class="my-0.5 ml-[19px] border-l border-tnv12-line pl-2 text-[13px] [&>li>a]:-ml-[9px] [&>li>a]:rounded-l-none [&>li>a]:border-l-2 [&>li>a]:border-transparent [&>li>a]:pl-3.5 [&>li>a[aria-current]]:border-tnv12-acc [&>li>a[aria-current]]:bg-tnv12-soft [&>li>a[aria-current]]:font-semibold [&>li>a[aria-current]]:text-tnv12-acc-ink">
<li><a href="#">Installation</a></li>
<li><a href="#" aria-current="page">Quick start guide</a></li>
<li><a href="#">Project structure</a></li>
<li><details class="group/l2">
<summary class="text-[13px]">Configuration<svg class="ml-auto size-3.5! opacity-60 transition-transform duration-200 group-open/l2:rotate-90" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M9 18l6-6-6-6"/></svg></summary>
<ul class="ml-3 border-l border-tnv12-line pl-2"><li><a href="#">Environment variables</a></li><li><a href="#">TypeScript config</a></li><li><a href="#">ESLint setup</a></li></ul>
</details></li>
</ul>
</details></li>
<li><details class="group/l1">
<summary><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/></svg>Components<span class="ml-auto rounded-full bg-tnv12-soft px-1.5 text-[10px] font-semibold text-tnv12-acc-ink">5</span><svg class="size-3.5! opacity-60 transition-transform duration-200 group-open/l1:rotate-90" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M9 18l6-6-6-6"/></svg></summary>
<ul class="my-0.5 ml-[19px] border-l border-tnv12-line pl-2 text-[13px]"><li><a href="#">Button</a></li><li><a href="#">Input</a></li><li><a href="#">Modal</a></li><li><a href="#">Navigation</a></li><li><a href="#">Table</a></li></ul>
</details></li>
<li><details class="group/l1">
<summary><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M16 18l6-6-6-6M8 6l-6 6 6 6"/></svg>API Reference<svg class="ml-auto size-3.5! opacity-60 transition-transform duration-200 group-open/l1:rotate-90" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M9 18l6-6-6-6"/></svg></summary>
<ul class="my-0.5 ml-[19px] border-l border-tnv12-line pl-2 text-[13px]"><li><a href="#">Authentication</a></li><li><a href="#">Endpoints</a></li><li><a href="#">Webhooks</a></li></ul>
</details></li>
<li><a href="#"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><circle cx="12" cy="12" r="10"/><path d="M9.09 9a3 3 0 015.83 1c0 2-3 3-3 3M12 17h.01"/></svg>FAQ</a></li>
</ul>
</nav>
</aside>
<main class="min-w-0 flex-1 px-6 py-10 sm:px-12 [&_code]:rounded [&_code]:bg-tnv12-soft [&_code]:px-1.5 [&_code]:font-tnv12-mono [&_code]:text-[0.85em] [&_code]:text-tnv12-acc-ink">
<p class="text-[13px] font-semibold text-tnv12-acc-ink">Getting Started</p>
<h1 class="mt-1 text-3xl font-semibold tracking-[-0.02em]">Quick start guide</h1>
<p class="mt-4 max-w-2xl text-[15px]/[1.75] text-tnv12-mut">Every section in the sidebar is a native <code><details></code>. It announces its state, opens with Enter or Space, and animates its height to <code>auto</code> with <code>::details-content</code>. Chevrons rotate with <code>group-open/l1:</code>.</p>
<pre class="mt-6 max-w-2xl overflow-x-auto rounded-xl bg-slate-900 p-5 font-tnv12-mono text-[13px]/[1.7] text-slate-300"><span class="text-slate-500">/* the only CSS left */</span>
.tnv-12 { <span class="text-sky-300">interpolate-size</span>: allow-keywords; }
.tnv-12 details::details-content {
<span class="text-sky-300">block-size</span>: <span class="text-emerald-300">0</span>; overflow: hidden;
transition: block-size .3s, content-visibility .3s allow-discrete;
}
.tnv-12 details[open]::details-content { <span class="text-sky-300">block-size</span>: <span class="text-emerald-300">auto</span>; }</pre>
</main>
</div><div class="tnv-12 flex min-h-svh w-full flex-col bg-tnv12-bg font-tnv12-sans text-tnv12-ink antialiased selection:bg-tnv12-acc selection:text-white md:flex-row">
<aside class="flex w-full flex-none flex-col border-b border-tnv12-line bg-white md:sticky md:top-0 md:h-svh md:w-[17rem] md:border-r md:border-b-0">
<div class="flex items-center gap-2.5 border-b border-tnv12-line px-4 py-4">
<span class="grid size-8 place-items-center rounded-lg bg-tnv12-acc"><svg class="size-4" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" aria-hidden="true"><path d="M2 3h6a4 4 0 014 4v14a3 3 0 00-3-3H2zM22 3h-6a4 4 0 00-4 4v14a3 3 0 013-3h7z"/></svg></span>
<span class="font-semibold"><span class="text-tnv12-acc-ink">Dev</span>Docs</span>
<span class="ml-auto rounded-md bg-tnv12-soft px-1.5 py-0.5 font-tnv12-mono text-[11px] font-medium text-tnv12-acc-ink">v4.2</span>
</div>
<div class="border-b border-tnv12-line p-3">
<button type="button" class="flex h-10 w-full items-center gap-2 rounded-lg border border-tnv12-line bg-tnv12-bg px-3 text-left text-[13px] text-tnv12-mut transition-colors hover:border-slate-300"><svg class="size-4 flex-none" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><circle cx="11" cy="11" r="8"/><path d="M21 21l-4.35-4.35"/></svg>Search docs<kbd class="ml-auto rounded border border-tnv12-line bg-white px-1.5 font-tnv12-mono text-[10px]">⌘K</kbd></button>
</div>
<nav aria-label="Documentation" class="flex-1 overflow-y-auto p-2 text-sm font-medium text-tnv12-mut [&_summary]:flex [&_summary]:min-h-10 [&_summary]:cursor-pointer [&_summary]:list-none [&_summary]:items-center [&_summary]:gap-2.5 [&_summary]:rounded-lg [&_summary]:px-2.5 [&_summary]:transition-colors [&_summary]:select-none [&_summary:hover]:bg-tnv12-bg [&_summary:hover]:text-tnv12-ink [&_summary:focus-visible]:outline-2 [&_summary:focus-visible]:outline-tnv12-acc [&_summary::-webkit-details-marker]:hidden [&_a]:flex [&_a]:min-h-10 [&_a]:items-center [&_a]:gap-2.5 [&_a]:rounded-lg [&_a]:px-2.5 [&_a]:transition-colors [&_a:hover]:bg-tnv12-bg [&_a:hover]:text-tnv12-ink [&_a:focus-visible]:outline-2 [&_a:focus-visible]:outline-tnv12-acc [&_svg]:size-4 [&_svg]:flex-none">
<ul class="space-y-0.5">
<li><a href="#"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M3 9l9-7 9 7v11a2 2 0 01-2 2H5a2 2 0 01-2-2z"/></svg>Introduction</a></li>
<li><details open class="group/l1">
<summary><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M22 19a2 2 0 01-2 2H4a2 2 0 01-2-2V5a2 2 0 012-2h5l2 3h9a2 2 0 012 2z"/></svg>Getting Started<svg class="ml-auto size-3.5! opacity-60 transition-transform duration-200 group-open/l1:rotate-90" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M9 18l6-6-6-6"/></svg></summary>
<ul class="my-0.5 ml-[19px] border-l border-tnv12-line pl-2 text-[13px] [&>li>a]:-ml-[9px] [&>li>a]:rounded-l-none [&>li>a]:border-l-2 [&>li>a]:border-transparent [&>li>a]:pl-3.5 [&>li>a[aria-current]]:border-tnv12-acc [&>li>a[aria-current]]:bg-tnv12-soft [&>li>a[aria-current]]:font-semibold [&>li>a[aria-current]]:text-tnv12-acc-ink">
<li><a href="#">Installation</a></li>
<li><a href="#" aria-current="page">Quick start guide</a></li>
<li><a href="#">Project structure</a></li>
<li><details class="group/l2">
<summary class="text-[13px]">Configuration<svg class="ml-auto size-3.5! opacity-60 transition-transform duration-200 group-open/l2:rotate-90" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M9 18l6-6-6-6"/></svg></summary>
<ul class="ml-3 border-l border-tnv12-line pl-2"><li><a href="#">Environment variables</a></li><li><a href="#">TypeScript config</a></li><li><a href="#">ESLint setup</a></li></ul>
</details></li>
</ul>
</details></li>
<li><details class="group/l1">
<summary><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/></svg>Components<span class="ml-auto rounded-full bg-tnv12-soft px-1.5 text-[10px] font-semibold text-tnv12-acc-ink">5</span><svg class="size-3.5! opacity-60 transition-transform duration-200 group-open/l1:rotate-90" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M9 18l6-6-6-6"/></svg></summary>
<ul class="my-0.5 ml-[19px] border-l border-tnv12-line pl-2 text-[13px]"><li><a href="#">Button</a></li><li><a href="#">Input</a></li><li><a href="#">Modal</a></li><li><a href="#">Navigation</a></li><li><a href="#">Table</a></li></ul>
</details></li>
<li><details class="group/l1">
<summary><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M16 18l6-6-6-6M8 6l-6 6 6 6"/></svg>API Reference<svg class="ml-auto size-3.5! opacity-60 transition-transform duration-200 group-open/l1:rotate-90" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M9 18l6-6-6-6"/></svg></summary>
<ul class="my-0.5 ml-[19px] border-l border-tnv12-line pl-2 text-[13px]"><li><a href="#">Authentication</a></li><li><a href="#">Endpoints</a></li><li><a href="#">Webhooks</a></li></ul>
</details></li>
<li><a href="#"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><circle cx="12" cy="12" r="10"/><path d="M9.09 9a3 3 0 015.83 1c0 2-3 3-3 3M12 17h.01"/></svg>FAQ</a></li>
</ul>
</nav>
</aside>
<main class="min-w-0 flex-1 px-6 py-10 sm:px-12 [&_code]:rounded [&_code]:bg-tnv12-soft [&_code]:px-1.5 [&_code]:font-tnv12-mono [&_code]:text-[0.85em] [&_code]:text-tnv12-acc-ink">
<p class="text-[13px] font-semibold text-tnv12-acc-ink">Getting Started</p>
<h1 class="mt-1 text-3xl font-semibold tracking-[-0.02em]">Quick start guide</h1>
<p class="mt-4 max-w-2xl text-[15px]/[1.75] text-tnv12-mut">Every section in the sidebar is a native <code><details></code>. It announces its state, opens with Enter or Space, and animates its height to <code>auto</code> with <code>::details-content</code>. Chevrons rotate with <code>group-open/l1:</code>.</p>
<pre class="mt-6 max-w-2xl overflow-x-auto rounded-xl bg-slate-900 p-5 font-tnv12-mono text-[13px]/[1.7] text-slate-300"><span class="text-slate-500">/* the only CSS left */</span>
.tnv-12 { <span class="text-sky-300">interpolate-size</span>: allow-keywords; }
.tnv-12 details::details-content {
<span class="text-sky-300">block-size</span>: <span class="text-emerald-300">0</span>; overflow: hidden;
transition: block-size .3s, content-visibility .3s allow-discrete;
}
.tnv-12 details[open]::details-content { <span class="text-sky-300">block-size</span>: <span class="text-emerald-300">auto</span>; }</pre>
</main>
</div>@import "tailwindcss";
@theme {
--color-tnv12-bg: #f8fafc;
--color-tnv12-bg: oklch(0.984 0.003 248);
--color-tnv12-soft: #ecfeff;
--color-tnv12-soft: oklch(0.984 0.019 201);
--color-tnv12-line: #e2e8f0;
--color-tnv12-line: oklch(0.929 0.013 256);
--color-tnv12-ink: #1e293b;
--color-tnv12-ink: oklch(0.279 0.041 260);
--color-tnv12-mut: #475569;
--color-tnv12-mut: oklch(0.446 0.043 257);
--color-tnv12-acc: #0891b2;
--color-tnv12-acc: oklch(0.609 0.126 222);
--color-tnv12-acc-ink: #0e7490;
--color-tnv12-acc-ink: oklch(0.52 0.105 223);
--font-tnv12-sans: 'Rubik', system-ui, sans-serif;
--font-tnv12-mono: 'IBM Plex Mono', ui-monospace, monospace;
}
.tnv-12 {
width: 100%;
min-height: 100svh;
interpolate-size: allow-keywords;
}
/* ::details-content has no Tailwind variant, so the height animation stays CSS. */
.tnv-12 details::details-content {
block-size: 0;
overflow: hidden;
transition: block-size 0.3s ease, content-visibility 0.3s allow-discrete;
}
.tnv-12 details[open]::details-content {
block-size: auto;
}
@media (prefers-reduced-motion: reduce) {
.tnv-12 details::details-content {
transition: none;
}
}@import "tailwindcss";
@theme {
--color-tnv12-bg: #f8fafc;
--color-tnv12-bg: oklch(0.984 0.003 248);
--color-tnv12-soft: #ecfeff;
--color-tnv12-soft: oklch(0.984 0.019 201);
--color-tnv12-line: #e2e8f0;
--color-tnv12-line: oklch(0.929 0.013 256);
--color-tnv12-ink: #1e293b;
--color-tnv12-ink: oklch(0.279 0.041 260);
--color-tnv12-mut: #475569;
--color-tnv12-mut: oklch(0.446 0.043 257);
--color-tnv12-acc: #0891b2;
--color-tnv12-acc: oklch(0.609 0.126 222);
--color-tnv12-acc-ink: #0e7490;
--color-tnv12-acc-ink: oklch(0.52 0.105 223);
--font-tnv12-sans: 'Rubik', system-ui, sans-serif;
--font-tnv12-mono: 'IBM Plex Mono', ui-monospace, monospace;
}
.tnv-12 {
width: 100%;
min-height: 100svh;
interpolate-size: allow-keywords;
}
/* ::details-content has no Tailwind variant, so the height animation stays CSS. */
.tnv-12 details::details-content {
block-size: 0;
overflow: hidden;
transition: block-size 0.3s ease, content-visibility 0.3s allow-discrete;
}
.tnv-12 details[open]::details-content {
block-size: auto;
}
@media (prefers-reduced-motion: reduce) {
.tnv-12 details::details-content {
transition: none;
}
}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-tnv12-bg: #f8fafc;
--color-tnv12-bg: oklch(0.984 0.003 248);
--color-tnv12-soft: #ecfeff;
--color-tnv12-soft: oklch(0.984 0.019 201);
--color-tnv12-line: #e2e8f0;
--color-tnv12-line: oklch(0.929 0.013 256);
--color-tnv12-ink: #1e293b;
--color-tnv12-ink: oklch(0.279 0.041 260);
--color-tnv12-mut: #475569;
--color-tnv12-mut: oklch(0.446 0.043 257);
--color-tnv12-acc: #0891b2;
--color-tnv12-acc: oklch(0.609 0.126 222);
--color-tnv12-acc-ink: #0e7490;
--color-tnv12-acc-ink: oklch(0.52 0.105 223);
--font-tnv12-sans: 'Rubik', system-ui, sans-serif;
--font-tnv12-mono: 'IBM Plex Mono', ui-monospace, monospace;
}
.tnv-12 {
width: 100%;
min-height: 100svh;
interpolate-size: allow-keywords;
}
/* ::details-content has no Tailwind variant, so the height animation stays CSS. */
.tnv-12 details::details-content {
block-size: 0;
overflow: hidden;
transition: block-size 0.3s ease, content-visibility 0.3s allow-discrete;
}
.tnv-12 details[open]::details-content {
block-size: auto;
}
@media (prefers-reduced-motion: reduce) {
.tnv-12 details::details-content {
transition: none;
}
}@import "tailwindcss";
@theme {
--color-tnv12-bg: #f8fafc;
--color-tnv12-bg: oklch(0.984 0.003 248);
--color-tnv12-soft: #ecfeff;
--color-tnv12-soft: oklch(0.984 0.019 201);
--color-tnv12-line: #e2e8f0;
--color-tnv12-line: oklch(0.929 0.013 256);
--color-tnv12-ink: #1e293b;
--color-tnv12-ink: oklch(0.279 0.041 260);
--color-tnv12-mut: #475569;
--color-tnv12-mut: oklch(0.446 0.043 257);
--color-tnv12-acc: #0891b2;
--color-tnv12-acc: oklch(0.609 0.126 222);
--color-tnv12-acc-ink: #0e7490;
--color-tnv12-acc-ink: oklch(0.52 0.105 223);
--font-tnv12-sans: 'Rubik', system-ui, sans-serif;
--font-tnv12-mono: 'IBM Plex Mono', ui-monospace, monospace;
}
.tnv-12 {
width: 100%;
min-height: 100svh;
interpolate-size: allow-keywords;
}
/* ::details-content has no Tailwind variant, so the height animation stays CSS. */
.tnv-12 details::details-content {
block-size: 0;
overflow: hidden;
transition: block-size 0.3s ease, content-visibility 0.3s allow-discrete;
}
.tnv-12 details[open]::details-content {
block-size: auto;
}
@media (prefers-reduced-motion: reduce) {
.tnv-12 details::details-content {
transition: none;
}
}<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=Rubik:wght@400..700&family=IBM+Plex+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=Rubik:wght@400..700&family=IBM+Plex+Mono:wght@400;500&display=swap">What changed in the port
Which parts became utilities, which stayed CSS, and why.
- Four hidden checkboxes and eight
:checked ~ *rules were replaced by native<details>andgroup-open/l1:/group-open/l2:utilities. - What stayed CSS: the
::details-contentheight animation andinterpolate-size— a pseudo-element with no variant. - Upgrade from the CSS original: its own gotcha flagged the imprecise
max-heighttrick; the height now animates to its trueautovalue at a uniform speed. - Accessibility & UI upgrade: sections announce expanded/collapsed and open from the keyboard; tree guide lines and an
aria-currentrail mark the active page; the sidebar stacks above content on phones instead of squeezing to 220px.
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 Multi-Level Accordion Sidebar Menu
Source: https://codefronts.com/navigation/tailwind-css-navigation-menus/tailwind-css-multi-level-accordion-sidebar-menu/
A documentation-site sidebar with nested, animated sections. The checkbox hack is gone: every section is a native <details>, so it announces expanded/collapsed, works with Enter and Space, and opens for find-in-page. Height animates to auto through ::details-content with interpolate-size; chevrons turn with group-open/l1:. Zero JavaScript.
## HTML
```html
<div class="tnv-12 flex min-h-svh w-full flex-col bg-tnv12-bg font-tnv12-sans text-tnv12-ink antialiased selection:bg-tnv12-acc selection:text-white md:flex-row">
<aside class="flex w-full flex-none flex-col border-b border-tnv12-line bg-white md:sticky md:top-0 md:h-svh md:w-[17rem] md:border-r md:border-b-0">
<div class="flex items-center gap-2.5 border-b border-tnv12-line px-4 py-4">
<span class="grid size-8 place-items-center rounded-lg bg-tnv12-acc"><svg class="size-4" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" aria-hidden="true"><path d="M2 3h6a4 4 0 014 4v14a3 3 0 00-3-3H2zM22 3h-6a4 4 0 00-4 4v14a3 3 0 013-3h7z"/></svg></span>
<span class="font-semibold"><span class="text-tnv12-acc-ink">Dev</span>Docs</span>
<span class="ml-auto rounded-md bg-tnv12-soft px-1.5 py-0.5 font-tnv12-mono text-[11px] font-medium text-tnv12-acc-ink">v4.2</span>
</div>
<div class="border-b border-tnv12-line p-3">
<button type="button" class="flex h-10 w-full items-center gap-2 rounded-lg border border-tnv12-line bg-tnv12-bg px-3 text-left text-[13px] text-tnv12-mut transition-colors hover:border-slate-300"><svg class="size-4 flex-none" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><circle cx="11" cy="11" r="8"/><path d="M21 21l-4.35-4.35"/></svg>Search docs<kbd class="ml-auto rounded border border-tnv12-line bg-white px-1.5 font-tnv12-mono text-[10px]">⌘K</kbd></button>
</div>
<nav aria-label="Documentation" class="flex-1 overflow-y-auto p-2 text-sm font-medium text-tnv12-mut [&_summary]:flex [&_summary]:min-h-10 [&_summary]:cursor-pointer [&_summary]:list-none [&_summary]:items-center [&_summary]:gap-2.5 [&_summary]:rounded-lg [&_summary]:px-2.5 [&_summary]:transition-colors [&_summary]:select-none [&_summary:hover]:bg-tnv12-bg [&_summary:hover]:text-tnv12-ink [&_summary:focus-visible]:outline-2 [&_summary:focus-visible]:outline-tnv12-acc [&_summary::-webkit-details-marker]:hidden [&_a]:flex [&_a]:min-h-10 [&_a]:items-center [&_a]:gap-2.5 [&_a]:rounded-lg [&_a]:px-2.5 [&_a]:transition-colors [&_a:hover]:bg-tnv12-bg [&_a:hover]:text-tnv12-ink [&_a:focus-visible]:outline-2 [&_a:focus-visible]:outline-tnv12-acc [&_svg]:size-4 [&_svg]:flex-none">
<ul class="space-y-0.5">
<li><a href="#"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M3 9l9-7 9 7v11a2 2 0 01-2 2H5a2 2 0 01-2-2z"/></svg>Introduction</a></li>
<li><details open class="group/l1">
<summary><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M22 19a2 2 0 01-2 2H4a2 2 0 01-2-2V5a2 2 0 012-2h5l2 3h9a2 2 0 012 2z"/></svg>Getting Started<svg class="ml-auto size-3.5! opacity-60 transition-transform duration-200 group-open/l1:rotate-90" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M9 18l6-6-6-6"/></svg></summary>
<ul class="my-0.5 ml-[19px] border-l border-tnv12-line pl-2 text-[13px] [&>li>a]:-ml-[9px] [&>li>a]:rounded-l-none [&>li>a]:border-l-2 [&>li>a]:border-transparent [&>li>a]:pl-3.5 [&>li>a[aria-current]]:border-tnv12-acc [&>li>a[aria-current]]:bg-tnv12-soft [&>li>a[aria-current]]:font-semibold [&>li>a[aria-current]]:text-tnv12-acc-ink">
<li><a href="#">Installation</a></li>
<li><a href="#" aria-current="page">Quick start guide</a></li>
<li><a href="#">Project structure</a></li>
<li><details class="group/l2">
<summary class="text-[13px]">Configuration<svg class="ml-auto size-3.5! opacity-60 transition-transform duration-200 group-open/l2:rotate-90" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M9 18l6-6-6-6"/></svg></summary>
<ul class="ml-3 border-l border-tnv12-line pl-2"><li><a href="#">Environment variables</a></li><li><a href="#">TypeScript config</a></li><li><a href="#">ESLint setup</a></li></ul>
</details></li>
</ul>
</details></li>
<li><details class="group/l1">
<summary><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/></svg>Components<span class="ml-auto rounded-full bg-tnv12-soft px-1.5 text-[10px] font-semibold text-tnv12-acc-ink">5</span><svg class="size-3.5! opacity-60 transition-transform duration-200 group-open/l1:rotate-90" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M9 18l6-6-6-6"/></svg></summary>
<ul class="my-0.5 ml-[19px] border-l border-tnv12-line pl-2 text-[13px]"><li><a href="#">Button</a></li><li><a href="#">Input</a></li><li><a href="#">Modal</a></li><li><a href="#">Navigation</a></li><li><a href="#">Table</a></li></ul>
</details></li>
<li><details class="group/l1">
<summary><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M16 18l6-6-6-6M8 6l-6 6 6 6"/></svg>API Reference<svg class="ml-auto size-3.5! opacity-60 transition-transform duration-200 group-open/l1:rotate-90" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M9 18l6-6-6-6"/></svg></summary>
<ul class="my-0.5 ml-[19px] border-l border-tnv12-line pl-2 text-[13px]"><li><a href="#">Authentication</a></li><li><a href="#">Endpoints</a></li><li><a href="#">Webhooks</a></li></ul>
</details></li>
<li><a href="#"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><circle cx="12" cy="12" r="10"/><path d="M9.09 9a3 3 0 015.83 1c0 2-3 3-3 3M12 17h.01"/></svg>FAQ</a></li>
</ul>
</nav>
</aside>
<main class="min-w-0 flex-1 px-6 py-10 sm:px-12 [&_code]:rounded [&_code]:bg-tnv12-soft [&_code]:px-1.5 [&_code]:font-tnv12-mono [&_code]:text-[0.85em] [&_code]:text-tnv12-acc-ink">
<p class="text-[13px] font-semibold text-tnv12-acc-ink">Getting Started</p>
<h1 class="mt-1 text-3xl font-semibold tracking-[-0.02em]">Quick start guide</h1>
<p class="mt-4 max-w-2xl text-[15px]/[1.75] text-tnv12-mut">Every section in the sidebar is a native <code><details></code>. It announces its state, opens with Enter or Space, and animates its height to <code>auto</code> with <code>::details-content</code>. Chevrons rotate with <code>group-open/l1:</code>.</p>
<pre class="mt-6 max-w-2xl overflow-x-auto rounded-xl bg-slate-900 p-5 font-tnv12-mono text-[13px]/[1.7] text-slate-300"><span class="text-slate-500">/* the only CSS left */</span>
.tnv-12 { <span class="text-sky-300">interpolate-size</span>: allow-keywords; }
.tnv-12 details::details-content {
<span class="text-sky-300">block-size</span>: <span class="text-emerald-300">0</span>; overflow: hidden;
transition: block-size .3s, content-visibility .3s allow-discrete;
}
.tnv-12 details[open]::details-content { <span class="text-sky-300">block-size</span>: <span class="text-emerald-300">auto</span>; }</pre>
</main>
</div>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tnv12-bg: #f8fafc;
--color-tnv12-bg: oklch(0.984 0.003 248);
--color-tnv12-soft: #ecfeff;
--color-tnv12-soft: oklch(0.984 0.019 201);
--color-tnv12-line: #e2e8f0;
--color-tnv12-line: oklch(0.929 0.013 256);
--color-tnv12-ink: #1e293b;
--color-tnv12-ink: oklch(0.279 0.041 260);
--color-tnv12-mut: #475569;
--color-tnv12-mut: oklch(0.446 0.043 257);
--color-tnv12-acc: #0891b2;
--color-tnv12-acc: oklch(0.609 0.126 222);
--color-tnv12-acc-ink: #0e7490;
--color-tnv12-acc-ink: oklch(0.52 0.105 223);
--font-tnv12-sans: 'Rubik', system-ui, sans-serif;
--font-tnv12-mono: 'IBM Plex Mono', ui-monospace, monospace;
}
.tnv-12 {
width: 100%;
min-height: 100svh;
interpolate-size: allow-keywords;
}
/* ::details-content has no Tailwind variant, so the height animation stays CSS. */
.tnv-12 details::details-content {
block-size: 0;
overflow: hidden;
transition: block-size 0.3s ease, content-visibility 0.3s allow-discrete;
}
.tnv-12 details[open]::details-content {
block-size: auto;
}
@media (prefers-reduced-motion: reduce) {
.tnv-12 details::details-content {
transition: none;
}
}
```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 Multi-Level Accordion Sidebar Menu
Source: https://codefronts.com/navigation/tailwind-css-navigation-menus/tailwind-css-multi-level-accordion-sidebar-menu/
A documentation-site sidebar with nested, animated sections. The checkbox hack is gone: every section is a native <details>, so it announces expanded/collapsed, works with Enter and Space, and opens for find-in-page. Height animates to auto through ::details-content with interpolate-size; chevrons turn with group-open/l1:. Zero JavaScript.
## HTML
```html
<div class="tnv-12 flex min-h-svh w-full flex-col bg-tnv12-bg font-tnv12-sans text-tnv12-ink antialiased selection:bg-tnv12-acc selection:text-white md:flex-row">
<aside class="flex w-full flex-none flex-col border-b border-tnv12-line bg-white md:sticky md:top-0 md:h-svh md:w-[17rem] md:border-r md:border-b-0">
<div class="flex items-center gap-2.5 border-b border-tnv12-line px-4 py-4">
<span class="grid size-8 place-items-center rounded-lg bg-tnv12-acc"><svg class="size-4" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" aria-hidden="true"><path d="M2 3h6a4 4 0 014 4v14a3 3 0 00-3-3H2zM22 3h-6a4 4 0 00-4 4v14a3 3 0 013-3h7z"/></svg></span>
<span class="font-semibold"><span class="text-tnv12-acc-ink">Dev</span>Docs</span>
<span class="ml-auto rounded-md bg-tnv12-soft px-1.5 py-0.5 font-tnv12-mono text-[11px] font-medium text-tnv12-acc-ink">v4.2</span>
</div>
<div class="border-b border-tnv12-line p-3">
<button type="button" class="flex h-10 w-full items-center gap-2 rounded-lg border border-tnv12-line bg-tnv12-bg px-3 text-left text-[13px] text-tnv12-mut transition-colors hover:border-slate-300"><svg class="size-4 flex-none" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><circle cx="11" cy="11" r="8"/><path d="M21 21l-4.35-4.35"/></svg>Search docs<kbd class="ml-auto rounded border border-tnv12-line bg-white px-1.5 font-tnv12-mono text-[10px]">⌘K</kbd></button>
</div>
<nav aria-label="Documentation" class="flex-1 overflow-y-auto p-2 text-sm font-medium text-tnv12-mut [&_summary]:flex [&_summary]:min-h-10 [&_summary]:cursor-pointer [&_summary]:list-none [&_summary]:items-center [&_summary]:gap-2.5 [&_summary]:rounded-lg [&_summary]:px-2.5 [&_summary]:transition-colors [&_summary]:select-none [&_summary:hover]:bg-tnv12-bg [&_summary:hover]:text-tnv12-ink [&_summary:focus-visible]:outline-2 [&_summary:focus-visible]:outline-tnv12-acc [&_summary::-webkit-details-marker]:hidden [&_a]:flex [&_a]:min-h-10 [&_a]:items-center [&_a]:gap-2.5 [&_a]:rounded-lg [&_a]:px-2.5 [&_a]:transition-colors [&_a:hover]:bg-tnv12-bg [&_a:hover]:text-tnv12-ink [&_a:focus-visible]:outline-2 [&_a:focus-visible]:outline-tnv12-acc [&_svg]:size-4 [&_svg]:flex-none">
<ul class="space-y-0.5">
<li><a href="#"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M3 9l9-7 9 7v11a2 2 0 01-2 2H5a2 2 0 01-2-2z"/></svg>Introduction</a></li>
<li><details open class="group/l1">
<summary><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M22 19a2 2 0 01-2 2H4a2 2 0 01-2-2V5a2 2 0 012-2h5l2 3h9a2 2 0 012 2z"/></svg>Getting Started<svg class="ml-auto size-3.5! opacity-60 transition-transform duration-200 group-open/l1:rotate-90" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M9 18l6-6-6-6"/></svg></summary>
<ul class="my-0.5 ml-[19px] border-l border-tnv12-line pl-2 text-[13px] [&>li>a]:-ml-[9px] [&>li>a]:rounded-l-none [&>li>a]:border-l-2 [&>li>a]:border-transparent [&>li>a]:pl-3.5 [&>li>a[aria-current]]:border-tnv12-acc [&>li>a[aria-current]]:bg-tnv12-soft [&>li>a[aria-current]]:font-semibold [&>li>a[aria-current]]:text-tnv12-acc-ink">
<li><a href="#">Installation</a></li>
<li><a href="#" aria-current="page">Quick start guide</a></li>
<li><a href="#">Project structure</a></li>
<li><details class="group/l2">
<summary class="text-[13px]">Configuration<svg class="ml-auto size-3.5! opacity-60 transition-transform duration-200 group-open/l2:rotate-90" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M9 18l6-6-6-6"/></svg></summary>
<ul class="ml-3 border-l border-tnv12-line pl-2"><li><a href="#">Environment variables</a></li><li><a href="#">TypeScript config</a></li><li><a href="#">ESLint setup</a></li></ul>
</details></li>
</ul>
</details></li>
<li><details class="group/l1">
<summary><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/></svg>Components<span class="ml-auto rounded-full bg-tnv12-soft px-1.5 text-[10px] font-semibold text-tnv12-acc-ink">5</span><svg class="size-3.5! opacity-60 transition-transform duration-200 group-open/l1:rotate-90" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M9 18l6-6-6-6"/></svg></summary>
<ul class="my-0.5 ml-[19px] border-l border-tnv12-line pl-2 text-[13px]"><li><a href="#">Button</a></li><li><a href="#">Input</a></li><li><a href="#">Modal</a></li><li><a href="#">Navigation</a></li><li><a href="#">Table</a></li></ul>
</details></li>
<li><details class="group/l1">
<summary><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M16 18l6-6-6-6M8 6l-6 6 6 6"/></svg>API Reference<svg class="ml-auto size-3.5! opacity-60 transition-transform duration-200 group-open/l1:rotate-90" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M9 18l6-6-6-6"/></svg></summary>
<ul class="my-0.5 ml-[19px] border-l border-tnv12-line pl-2 text-[13px]"><li><a href="#">Authentication</a></li><li><a href="#">Endpoints</a></li><li><a href="#">Webhooks</a></li></ul>
</details></li>
<li><a href="#"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><circle cx="12" cy="12" r="10"/><path d="M9.09 9a3 3 0 015.83 1c0 2-3 3-3 3M12 17h.01"/></svg>FAQ</a></li>
</ul>
</nav>
</aside>
<main class="min-w-0 flex-1 px-6 py-10 sm:px-12 [&_code]:rounded [&_code]:bg-tnv12-soft [&_code]:px-1.5 [&_code]:font-tnv12-mono [&_code]:text-[0.85em] [&_code]:text-tnv12-acc-ink">
<p class="text-[13px] font-semibold text-tnv12-acc-ink">Getting Started</p>
<h1 class="mt-1 text-3xl font-semibold tracking-[-0.02em]">Quick start guide</h1>
<p class="mt-4 max-w-2xl text-[15px]/[1.75] text-tnv12-mut">Every section in the sidebar is a native <code><details></code>. It announces its state, opens with Enter or Space, and animates its height to <code>auto</code> with <code>::details-content</code>. Chevrons rotate with <code>group-open/l1:</code>.</p>
<pre class="mt-6 max-w-2xl overflow-x-auto rounded-xl bg-slate-900 p-5 font-tnv12-mono text-[13px]/[1.7] text-slate-300"><span class="text-slate-500">/* the only CSS left */</span>
.tnv-12 { <span class="text-sky-300">interpolate-size</span>: allow-keywords; }
.tnv-12 details::details-content {
<span class="text-sky-300">block-size</span>: <span class="text-emerald-300">0</span>; overflow: hidden;
transition: block-size .3s, content-visibility .3s allow-discrete;
}
.tnv-12 details[open]::details-content { <span class="text-sky-300">block-size</span>: <span class="text-emerald-300">auto</span>; }</pre>
</main>
</div>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tnv12-bg: #f8fafc;
--color-tnv12-bg: oklch(0.984 0.003 248);
--color-tnv12-soft: #ecfeff;
--color-tnv12-soft: oklch(0.984 0.019 201);
--color-tnv12-line: #e2e8f0;
--color-tnv12-line: oklch(0.929 0.013 256);
--color-tnv12-ink: #1e293b;
--color-tnv12-ink: oklch(0.279 0.041 260);
--color-tnv12-mut: #475569;
--color-tnv12-mut: oklch(0.446 0.043 257);
--color-tnv12-acc: #0891b2;
--color-tnv12-acc: oklch(0.609 0.126 222);
--color-tnv12-acc-ink: #0e7490;
--color-tnv12-acc-ink: oklch(0.52 0.105 223);
--font-tnv12-sans: 'Rubik', system-ui, sans-serif;
--font-tnv12-mono: 'IBM Plex Mono', ui-monospace, monospace;
}
.tnv-12 {
width: 100%;
min-height: 100svh;
interpolate-size: allow-keywords;
}
/* ::details-content has no Tailwind variant, so the height animation stays CSS. */
.tnv-12 details::details-content {
block-size: 0;
overflow: hidden;
transition: block-size 0.3s ease, content-visibility 0.3s allow-discrete;
}
.tnv-12 details[open]::details-content {
block-size: auto;
}
@media (prefers-reduced-motion: reduce) {
.tnv-12 details::details-content {
transition: none;
}
}
```How this works
Native disclosure beats a checkbox. The CSS original toggled hidden checkboxes; screen readers heard ‘checkbox, not checked’ for a menu. <details> is the platform's own accordion.
<details open class="group/l1">
<summary>Getting Started
<svg class="group-open/l1:rotate-90"></svg></summary>
<ul>…<details class="group/l2">…</ul>
</details>The one thing left in CSS is the height animation: ::details-content has no Tailwind variant, so four lines in the stylesheet give it block-size: 0 → auto with interpolate-size. Where unsupported, sections still open instantly.
Make it yours
- Exclusive accordion: give top-level sections the same
name="docs"attribute; opening one closes the others natively. - Tighter nesting: change
ml-[19px] pl-3on nested lists. - Slower motion: edit the
0.3sin the::details-contentrule.
Gotchas — read before shipping
- Named groups (
/l1,/l2) are required: an unnamedgroup-open:on the parent chevron would also react to a child section opening. interpolate-sizemust be set on an ancestor (here the root) forautoto interpolate.- Don't put interactive elements other than the label text inside
<summary>.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 129+ | not yet | not yet | 129+ |
Floor set by oklch(), interpolate-size as this demo is written. The core technique itself goes back further — Chrome 111+.
::details-content + interpolate-size animate in Chrome 131+; Safari and Firefox open sections instantly, fully functional.