Pure TailwindMIT licensed

Tailwind Accordion Sidebar Navigation for Documentation

A documentation sidebar with a search field, four independently collapsible sections and an active page marker. Each section animates to its true height with the grid-rows-[0fr] → grid-rows-[1fr] technique — no max-height guess — and every section header is reachable by Tab with a visible focus ring. Zero JavaScript.

Live Demo
Plain CSSTailwind v4
Try it

Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time

Untitled UI React · Affiliate link

Get Untitled UI Pro

The code

<section class="tsm-16 flex w-full min-h-svh bg-tsm16-bg font-tsm16-sans text-tsm16-ink" aria-label="Accordion sidebar navigation for documentation demo">
  <nav aria-label="Documentation" class="flex w-64 shrink-0 flex-col overflow-y-auto border-r border-tsm16-line bg-tsm16-surface">
    <div class="flex items-center gap-2.5 border-b border-tsm16-line px-4 py-[18px]">
      <span aria-hidden="true" class="grid size-8 place-items-center rounded-lg bg-tsm16-acc text-sm font-extrabold text-white">D</span>
      <p class="text-sm font-extrabold">DocBase <span class="ml-1 text-[10px] font-medium text-tsm16-mut2">v3.2</span></p>
    </div>
    <div class="border-b border-tsm16-line px-3.5 py-2.5">
      <label class="flex min-h-10 items-center gap-2 rounded-lg border border-tsm16-line bg-tsm16-bg px-3 text-tsm16-mut2 focus-within:border-tsm16-acc2 focus-within:ring-3 focus-within:ring-tsm16-acc/15">
        <svg class="size-4 shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="11" cy="11" r="7"/><path d="m20 20-3.5-3.5"/></svg>
        <span class="sr-only">Search documentation</span>
        <input type="search" placeholder="Search docs…" class="min-w-0 flex-1 bg-transparent text-xs text-tsm16-ink outline-none placeholder:text-tsm16-mut2">
        <kbd class="rounded border border-tsm16-line bg-tsm16-surface px-1.5 font-tsm16-mono text-[10px] text-tsm16-mut2">⌘K</kbd>
      </label>
    </div>
    <a href="#" class="flex min-h-11 items-center gap-2.5 border-b border-tsm16-line px-4 text-[13px] font-semibold text-tsm16-mut2 transition-colors hover:bg-tsm16-acc/4 hover:text-tsm16-acc focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tsm16-acc"><svg class="size-4 shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 10.5 12 3l9 7.5"/><path d="M5 9.5V20h14V9.5"/><path d="M10 20v-6h4v6"/></svg>Overview</a>
    <div class="group/sec border-b border-tsm16-line">
      <input type="checkbox" id="tsm-16-a1" class="sr-only" checked>
      <label for="tsm-16-a1" class="flex min-h-11 cursor-pointer items-center gap-2.5 px-4 text-xs font-bold tracking-[0.1em] text-tsm16-mut2 uppercase select-none transition-colors hover:bg-tsm16-acc/4 group-has-checked/sec:text-tsm16-acc group-has-[input:focus-visible]/sec:outline-2 group-has-[input:focus-visible]/sec:-outline-offset-2 group-has-[input:focus-visible]/sec:outline-tsm16-acc"><svg class="size-4 shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 15c-1.5 1.3-2 5-2 5s3.7-.5 5-2"/><path d="M9 15l-3-3c1.5-4 5-8.5 12-9-.5 7-5 10.5-9 12z"/><circle cx="14.5" cy="9.5" r="1.5"/></svg>Getting started<svg class="ml-auto size-3.5 shrink-0 transition-transform duration-300 group-has-checked/sec:rotate-90 motion-reduce:transition-none" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m9 6 6 6-6 6"/></svg></label>
      <div class="grid grid-rows-[0fr] transition-[grid-template-rows] duration-350 ease-[cubic-bezier(0.4,0,0.2,1)] group-has-checked/sec:grid-rows-[1fr] motion-reduce:transition-none">
        <ul class="invisible min-h-0 overflow-hidden pb-0 transition-[visibility] duration-350 group-has-checked/sec:visible group-has-checked/sec:pb-2"><li><a href="#" class="relative flex min-h-10 items-center gap-2.5 py-2 pr-4 pl-9 text-[13px] font-semibold text-tsm16-mut2 transition-colors before:absolute before:top-1/2 before:left-5 before:size-1 before:-translate-y-1/2 before:rounded-full before:bg-tsm16-mut before:transition-[background-color,scale] hover:bg-tsm16-acc/5 hover:text-tsm16-acc hover:before:scale-150 hover:before:bg-tsm16-acc focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tsm16-acc aria-[current=page]:bg-tsm16-acc/7 aria-[current=page]:text-tsm16-acc aria-[current=page]:before:bg-tsm16-acc" aria-current="page">Installation</a></li><li><a href="#" class="relative flex min-h-10 items-center gap-2.5 py-2 pr-4 pl-9 text-[13px] font-semibold text-tsm16-mut2 transition-colors before:absolute before:top-1/2 before:left-5 before:size-1 before:-translate-y-1/2 before:rounded-full before:bg-tsm16-mut before:transition-[background-color,scale] hover:bg-tsm16-acc/5 hover:text-tsm16-acc hover:before:scale-150 hover:before:bg-tsm16-acc focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tsm16-acc aria-[current=page]:bg-tsm16-acc/7 aria-[current=page]:text-tsm16-acc aria-[current=page]:before:bg-tsm16-acc">Configuration</a></li><li><a href="#" class="relative flex min-h-10 items-center gap-2.5 py-2 pr-4 pl-9 text-[13px] font-semibold text-tsm16-mut2 transition-colors before:absolute before:top-1/2 before:left-5 before:size-1 before:-translate-y-1/2 before:rounded-full before:bg-tsm16-mut before:transition-[background-color,scale] hover:bg-tsm16-acc/5 hover:text-tsm16-acc hover:before:scale-150 hover:before:bg-tsm16-acc focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tsm16-acc aria-[current=page]:bg-tsm16-acc/7 aria-[current=page]:text-tsm16-acc aria-[current=page]:before:bg-tsm16-acc">Quick start</a></li><li><a href="#" class="relative flex min-h-10 items-center gap-2.5 py-2 pr-4 pl-9 text-[13px] font-semibold text-tsm16-mut2 transition-colors before:absolute before:top-1/2 before:left-5 before:size-1 before:-translate-y-1/2 before:rounded-full before:bg-tsm16-mut before:transition-[background-color,scale] hover:bg-tsm16-acc/5 hover:text-tsm16-acc hover:before:scale-150 hover:before:bg-tsm16-acc focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tsm16-acc aria-[current=page]:bg-tsm16-acc/7 aria-[current=page]:text-tsm16-acc aria-[current=page]:before:bg-tsm16-acc">Examples</a></li></ul>
      </div>
    </div>
    <div class="group/sec border-b border-tsm16-line">
      <input type="checkbox" id="tsm-16-a2" class="sr-only">
      <label for="tsm-16-a2" class="flex min-h-11 cursor-pointer items-center gap-2.5 px-4 text-xs font-bold tracking-[0.1em] text-tsm16-mut2 uppercase select-none transition-colors hover:bg-tsm16-acc/4 group-has-checked/sec:text-tsm16-acc group-has-[input:focus-visible]/sec:outline-2 group-has-[input:focus-visible]/sec:-outline-offset-2 group-has-[input:focus-visible]/sec:outline-tsm16-acc"><svg class="size-4 shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m12 3 9 5-9 5-9-5z"/><path d="m3 13 9 5 9-5"/></svg>Core concepts<svg class="ml-auto size-3.5 shrink-0 transition-transform duration-300 group-has-checked/sec:rotate-90 motion-reduce:transition-none" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m9 6 6 6-6 6"/></svg></label>
      <div class="grid grid-rows-[0fr] transition-[grid-template-rows] duration-350 ease-[cubic-bezier(0.4,0,0.2,1)] group-has-checked/sec:grid-rows-[1fr] motion-reduce:transition-none">
        <ul class="invisible min-h-0 overflow-hidden pb-0 transition-[visibility] duration-350 group-has-checked/sec:visible group-has-checked/sec:pb-2"><li><a href="#" class="relative flex min-h-10 items-center gap-2.5 py-2 pr-4 pl-9 text-[13px] font-semibold text-tsm16-mut2 transition-colors before:absolute before:top-1/2 before:left-5 before:size-1 before:-translate-y-1/2 before:rounded-full before:bg-tsm16-mut before:transition-[background-color,scale] hover:bg-tsm16-acc/5 hover:text-tsm16-acc hover:before:scale-150 hover:before:bg-tsm16-acc focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tsm16-acc aria-[current=page]:bg-tsm16-acc/7 aria-[current=page]:text-tsm16-acc aria-[current=page]:before:bg-tsm16-acc">Architecture</a></li><li><a href="#" class="relative flex min-h-10 items-center gap-2.5 py-2 pr-4 pl-9 text-[13px] font-semibold text-tsm16-mut2 transition-colors before:absolute before:top-1/2 before:left-5 before:size-1 before:-translate-y-1/2 before:rounded-full before:bg-tsm16-mut before:transition-[background-color,scale] hover:bg-tsm16-acc/5 hover:text-tsm16-acc hover:before:scale-150 hover:before:bg-tsm16-acc focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tsm16-acc aria-[current=page]:bg-tsm16-acc/7 aria-[current=page]:text-tsm16-acc aria-[current=page]:before:bg-tsm16-acc">Data flow</a></li><li><a href="#" class="relative flex min-h-10 items-center gap-2.5 py-2 pr-4 pl-9 text-[13px] font-semibold text-tsm16-mut2 transition-colors before:absolute before:top-1/2 before:left-5 before:size-1 before:-translate-y-1/2 before:rounded-full before:bg-tsm16-mut before:transition-[background-color,scale] hover:bg-tsm16-acc/5 hover:text-tsm16-acc hover:before:scale-150 hover:before:bg-tsm16-acc focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tsm16-acc aria-[current=page]:bg-tsm16-acc/7 aria-[current=page]:text-tsm16-acc aria-[current=page]:before:bg-tsm16-acc">State management</a></li><li><a href="#" class="relative flex min-h-10 items-center gap-2.5 py-2 pr-4 pl-9 text-[13px] font-semibold text-tsm16-mut2 transition-colors before:absolute before:top-1/2 before:left-5 before:size-1 before:-translate-y-1/2 before:rounded-full before:bg-tsm16-mut before:transition-[background-color,scale] hover:bg-tsm16-acc/5 hover:text-tsm16-acc hover:before:scale-150 hover:before:bg-tsm16-acc focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tsm16-acc aria-[current=page]:bg-tsm16-acc/7 aria-[current=page]:text-tsm16-acc aria-[current=page]:before:bg-tsm16-acc">Routing</a></li></ul>
      </div>
    </div>
    <div class="group/sec border-b border-tsm16-line">
      <input type="checkbox" id="tsm-16-a3" class="sr-only">
      <label for="tsm-16-a3" class="flex min-h-11 cursor-pointer items-center gap-2.5 px-4 text-xs font-bold tracking-[0.1em] text-tsm16-mut2 uppercase select-none transition-colors hover:bg-tsm16-acc/4 group-has-checked/sec:text-tsm16-acc group-has-[input:focus-visible]/sec:outline-2 group-has-[input:focus-visible]/sec:-outline-offset-2 group-has-[input:focus-visible]/sec:outline-tsm16-acc"><svg class="size-4 shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m8 8-4 4 4 4"/><path d="m16 8 4 4-4 4"/></svg>API reference<svg class="ml-auto size-3.5 shrink-0 transition-transform duration-300 group-has-checked/sec:rotate-90 motion-reduce:transition-none" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m9 6 6 6-6 6"/></svg></label>
      <div class="grid grid-rows-[0fr] transition-[grid-template-rows] duration-350 ease-[cubic-bezier(0.4,0,0.2,1)] group-has-checked/sec:grid-rows-[1fr] motion-reduce:transition-none">
        <ul class="invisible min-h-0 overflow-hidden pb-0 transition-[visibility] duration-350 group-has-checked/sec:visible group-has-checked/sec:pb-2"><li><a href="#" class="relative flex min-h-10 items-center gap-2.5 py-2 pr-4 pl-9 text-[13px] font-semibold text-tsm16-mut2 transition-colors before:absolute before:top-1/2 before:left-5 before:size-1 before:-translate-y-1/2 before:rounded-full before:bg-tsm16-mut before:transition-[background-color,scale] hover:bg-tsm16-acc/5 hover:text-tsm16-acc hover:before:scale-150 hover:before:bg-tsm16-acc focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tsm16-acc aria-[current=page]:bg-tsm16-acc/7 aria-[current=page]:text-tsm16-acc aria-[current=page]:before:bg-tsm16-acc">Endpoints<span class="ml-auto rounded-full bg-tsm16-acc/12 px-1.5 text-[10px] font-bold text-tsm16-acc">48</span></a></li><li><a href="#" class="relative flex min-h-10 items-center gap-2.5 py-2 pr-4 pl-9 text-[13px] font-semibold text-tsm16-mut2 transition-colors before:absolute before:top-1/2 before:left-5 before:size-1 before:-translate-y-1/2 before:rounded-full before:bg-tsm16-mut before:transition-[background-color,scale] hover:bg-tsm16-acc/5 hover:text-tsm16-acc hover:before:scale-150 hover:before:bg-tsm16-acc focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tsm16-acc aria-[current=page]:bg-tsm16-acc/7 aria-[current=page]:text-tsm16-acc aria-[current=page]:before:bg-tsm16-acc">Authentication</a></li><li><a href="#" class="relative flex min-h-10 items-center gap-2.5 py-2 pr-4 pl-9 text-[13px] font-semibold text-tsm16-mut2 transition-colors before:absolute before:top-1/2 before:left-5 before:size-1 before:-translate-y-1/2 before:rounded-full before:bg-tsm16-mut before:transition-[background-color,scale] hover:bg-tsm16-acc/5 hover:text-tsm16-acc hover:before:scale-150 hover:before:bg-tsm16-acc focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tsm16-acc aria-[current=page]:bg-tsm16-acc/7 aria-[current=page]:text-tsm16-acc aria-[current=page]:before:bg-tsm16-acc">Webhooks</a></li><li><a href="#" class="relative flex min-h-10 items-center gap-2.5 py-2 pr-4 pl-9 text-[13px] font-semibold text-tsm16-mut2 transition-colors before:absolute before:top-1/2 before:left-5 before:size-1 before:-translate-y-1/2 before:rounded-full before:bg-tsm16-mut before:transition-[background-color,scale] hover:bg-tsm16-acc/5 hover:text-tsm16-acc hover:before:scale-150 hover:before:bg-tsm16-acc focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tsm16-acc aria-[current=page]:bg-tsm16-acc/7 aria-[current=page]:text-tsm16-acc aria-[current=page]:before:bg-tsm16-acc">Rate limits</a></li></ul>
      </div>
    </div>
    <div class="group/sec border-b border-tsm16-line">
      <input type="checkbox" id="tsm-16-a4" class="sr-only">
      <label for="tsm-16-a4" class="flex min-h-11 cursor-pointer items-center gap-2.5 px-4 text-xs font-bold tracking-[0.1em] text-tsm16-mut2 uppercase select-none transition-colors hover:bg-tsm16-acc/4 group-has-checked/sec:text-tsm16-acc group-has-[input:focus-visible]/sec:outline-2 group-has-[input:focus-visible]/sec:-outline-offset-2 group-has-[input:focus-visible]/sec:outline-tsm16-acc"><svg class="size-4 shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 19a2 2 0 0 1 2-2h14V3H6a2 2 0 0 0-2 2z"/><path d="M4 19a2 2 0 0 0 2 2h14v-4"/></svg>Guides<svg class="ml-auto size-3.5 shrink-0 transition-transform duration-300 group-has-checked/sec:rotate-90 motion-reduce:transition-none" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m9 6 6 6-6 6"/></svg></label>
      <div class="grid grid-rows-[0fr] transition-[grid-template-rows] duration-350 ease-[cubic-bezier(0.4,0,0.2,1)] group-has-checked/sec:grid-rows-[1fr] motion-reduce:transition-none">
        <ul class="invisible min-h-0 overflow-hidden pb-0 transition-[visibility] duration-350 group-has-checked/sec:visible group-has-checked/sec:pb-2"><li><a href="#" class="relative flex min-h-10 items-center gap-2.5 py-2 pr-4 pl-9 text-[13px] font-semibold text-tsm16-mut2 transition-colors before:absolute before:top-1/2 before:left-5 before:size-1 before:-translate-y-1/2 before:rounded-full before:bg-tsm16-mut before:transition-[background-color,scale] hover:bg-tsm16-acc/5 hover:text-tsm16-acc hover:before:scale-150 hover:before:bg-tsm16-acc focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tsm16-acc aria-[current=page]:bg-tsm16-acc/7 aria-[current=page]:text-tsm16-acc aria-[current=page]:before:bg-tsm16-acc">Deployment</a></li><li><a href="#" class="relative flex min-h-10 items-center gap-2.5 py-2 pr-4 pl-9 text-[13px] font-semibold text-tsm16-mut2 transition-colors before:absolute before:top-1/2 before:left-5 before:size-1 before:-translate-y-1/2 before:rounded-full before:bg-tsm16-mut before:transition-[background-color,scale] hover:bg-tsm16-acc/5 hover:text-tsm16-acc hover:before:scale-150 hover:before:bg-tsm16-acc focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tsm16-acc aria-[current=page]:bg-tsm16-acc/7 aria-[current=page]:text-tsm16-acc aria-[current=page]:before:bg-tsm16-acc">Performance</a></li><li><a href="#" class="relative flex min-h-10 items-center gap-2.5 py-2 pr-4 pl-9 text-[13px] font-semibold text-tsm16-mut2 transition-colors before:absolute before:top-1/2 before:left-5 before:size-1 before:-translate-y-1/2 before:rounded-full before:bg-tsm16-mut before:transition-[background-color,scale] hover:bg-tsm16-acc/5 hover:text-tsm16-acc hover:before:scale-150 hover:before:bg-tsm16-acc focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tsm16-acc aria-[current=page]:bg-tsm16-acc/7 aria-[current=page]:text-tsm16-acc aria-[current=page]:before:bg-tsm16-acc">Security</a></li></ul>
      </div>
    </div>
    <a href="#" class="flex min-h-11 items-center gap-2.5 border-b border-tsm16-line px-4 text-[13px] font-semibold text-tsm16-mut2 transition-colors hover:bg-tsm16-acc/4 hover:text-tsm16-acc focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tsm16-acc"><svg class="size-4 shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M14 3H6v18h12V7z"/><path d="M14 3v4h4"/><path d="M9 13h6M9 17h6"/></svg>Changelog</a>
  </nav>
  <div class="min-w-0 flex-1 p-6">
    <div class="mx-auto max-w-2xl">
      <h1 class="text-xl font-extrabold">Documentation</h1>
      <p class="mt-1.5 mb-6 max-w-prose text-[13px] leading-relaxed text-tsm16-mut2 text-pretty">Each sidebar section is a hidden checkbox and a <code class="rounded bg-tsm16-acc/8 px-1 font-tsm16-mono text-[12px] text-tsm16-acc">grid-rows-[0fr]</code> → <code class="rounded bg-tsm16-acc/8 px-1 font-tsm16-mono text-[12px] text-tsm16-acc">[1fr]</code> transition, so it opens to its real height.</p>
      <div class="grid gap-2.5">
        <a href="#" class="group/c flex items-center gap-3 rounded-xl border border-tsm16-line bg-tsm16-surface px-4 py-3.5 transition-[border-color,box-shadow,translate] hover:-translate-y-px hover:border-tsm16-acc2 hover:shadow-[0_4px_16px_oklch(0.55_0.2_262/0.1)] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tsm16-acc"><span class="grid size-9 shrink-0 place-items-center rounded-lg bg-tsm16-acc/8 text-tsm16-acc"><svg class="size-[18px] shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 4v11"/><path d="m7 10 5 5 5-5"/><path d="M5 20h14"/></svg></span><span class="min-w-0"><span class="block text-[13px] font-bold">Installation guide</span><span class="block text-xs text-tsm16-mut2">Set up your environment in under five minutes</span></span><svg class="ml-auto size-4 shrink-0 text-tsm16-mut transition-[translate,color] group-hover/c:translate-x-0.5 group-hover/c:text-tsm16-acc" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m9 6 6 6-6 6"/></svg></a>
        <a href="#" class="group/c flex items-center gap-3 rounded-xl border border-tsm16-line bg-tsm16-surface px-4 py-3.5 transition-[border-color,box-shadow,translate] hover:-translate-y-px hover:border-tsm16-acc2 hover:shadow-[0_4px_16px_oklch(0.55_0.2_262/0.1)] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tsm16-acc"><span class="grid size-9 shrink-0 place-items-center rounded-lg bg-tsm16-acc/8 text-tsm16-acc"><svg class="size-[18px] shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 6h9"/><path d="M19 6h1"/><circle cx="16" cy="6" r="2.5"/><path d="M4 12h2"/><path d="M12 12h8"/><circle cx="9" cy="12" r="2.5"/><path d="M4 18h11"/><circle cx="18" cy="18" r="2.5"/></svg></span><span class="min-w-0"><span class="block text-[13px] font-bold">Configuration reference</span><span class="block text-xs text-tsm16-mut2">Every option, with examples</span></span><svg class="ml-auto size-4 shrink-0 text-tsm16-mut transition-[translate,color] group-hover/c:translate-x-0.5 group-hover/c:text-tsm16-acc" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m9 6 6 6-6 6"/></svg></a>
        <a href="#" class="group/c flex items-center gap-3 rounded-xl border border-tsm16-line bg-tsm16-surface px-4 py-3.5 transition-[border-color,box-shadow,translate] hover:-translate-y-px hover:border-tsm16-acc2 hover:shadow-[0_4px_16px_oklch(0.55_0.2_262/0.1)] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tsm16-acc"><span class="grid size-9 shrink-0 place-items-center rounded-lg bg-tsm16-acc/8 text-tsm16-acc"><svg class="size-[18px] shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M13 2 4 14h7l-1 8 9-12h-7z"/></svg></span><span class="min-w-0"><span class="block text-[13px] font-bold">Quick-start tutorial</span><span class="block text-xs text-tsm16-mut2">Build your first integration in ten steps</span></span><svg class="ml-auto size-4 shrink-0 text-tsm16-mut transition-[translate,color] group-hover/c:translate-x-0.5 group-hover/c:text-tsm16-acc" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m9 6 6 6-6 6"/></svg></a>
      </div>
    </div>
  </div>
</section>
@import "tailwindcss";

@theme {
  --color-tsm16-bg: #f0f4ff;
  --color-tsm16-bg: oklch(0.967 0.015 270);
  --color-tsm16-surface: #ffffff;
  --color-tsm16-surface: oklch(1 0 0);
  --color-tsm16-line: #e2e8f0;
  --color-tsm16-line: oklch(0.929 0.013 255.5);
  --color-tsm16-acc: #2563eb;
  --color-tsm16-acc: oklch(0.546 0.215 262.9);
  --color-tsm16-acc2: #60a5fa;
  --color-tsm16-acc2: oklch(0.714 0.143 254.6);
  --color-tsm16-ink: #0f172a;
  --color-tsm16-ink: oklch(0.208 0.04 265.8);
  --color-tsm16-mut: #94a3b8;
  --color-tsm16-mut: oklch(0.711 0.035 256.8);
  --color-tsm16-mut2: #526075;
  --color-tsm16-mut2: oklch(0.485 0.038 258.4);
  --font-tsm16-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
  --font-tsm16-mono: 'JetBrains Mono', ui-monospace, monospace;
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's utilities, so the
   stage is sized before the browser build compiles. */

.tsm-16 {
  width: 100%;
  min-height: 100svh;
}

Setup — do this once per project

Skip this if your project already runs Tailwind v4.

1Load Tailwind
<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.

2Add the stylesheetRequiredthe @theme block is what makes the custom utilities exist
@import "tailwindcss";

@theme {
  --color-tsm16-bg: #f0f4ff;
  --color-tsm16-bg: oklch(0.967 0.015 270);
  --color-tsm16-surface: #ffffff;
  --color-tsm16-surface: oklch(1 0 0);
  --color-tsm16-line: #e2e8f0;
  --color-tsm16-line: oklch(0.929 0.013 255.5);
  --color-tsm16-acc: #2563eb;
  --color-tsm16-acc: oklch(0.546 0.215 262.9);
  --color-tsm16-acc2: #60a5fa;
  --color-tsm16-acc2: oklch(0.714 0.143 254.6);
  --color-tsm16-ink: #0f172a;
  --color-tsm16-ink: oklch(0.208 0.04 265.8);
  --color-tsm16-mut: #94a3b8;
  --color-tsm16-mut: oklch(0.711 0.035 256.8);
  --color-tsm16-mut2: #526075;
  --color-tsm16-mut2: oklch(0.485 0.038 258.4);
  --font-tsm16-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
  --font-tsm16-mono: 'JetBrains Mono', ui-monospace, monospace;
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's utilities, so the
   stage is sized before the browser build compiles. */

.tsm-16 {
  width: 100%;
  min-height: 100svh;
}
3Fonts used by this demooptional — skip if you have your own type stack
<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@500&display=swap">

What changed in the port

Which parts became utilities, which stayed CSS, and why.

  • max-height: 0 → 400px became grid-rows-[0fr] → grid-rows-[1fr] — the fix the original's own gotcha recommended — so sections ease to their true height with no magic number.
  • The :checked + .header + .items chain became group-has-checked/sec:; the input, label and list no longer have to be adjacent siblings.
  • UI upgrade from the CSS original: headers are keyboard-operable with a focus ring (the checkboxes were display:none), collapsed links are invisible, and the search field gained an icon, a label, a focus ring and a ⌘K hint.
  • UI upgrade: emoji doc icons were replaced with SVG icons in tinted tiles, doc cards became real links with a hover lift, and secondary text rose from #64748b to #526075 (6.4:1).
Paste this into ChatGPT, Claude, Cursor, or any coding assistant. The block below is pre-framed with everything the AI needs to integrate this demo into your project — markup, styles, scoping notes, and the source URL. Hit Copy and paste straight into your chat.
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 Accordion Sidebar Navigation for Documentation
Source: https://codefronts.com/navigation/tailwind-css-side-menus/tailwind-accordion-sidebar-navigation-documentation/

A documentation sidebar with a search field, four independently collapsible sections and an active page marker. Each section animates to its true height with the grid-rows-[0fr] → grid-rows-[1fr] technique — no max-height guess — and every section header is reachable by Tab with a visible focus ring. Zero JavaScript.
## HTML
```html
<section class="tsm-16 flex w-full min-h-svh bg-tsm16-bg font-tsm16-sans text-tsm16-ink" aria-label="Accordion sidebar navigation for documentation demo">
  <nav aria-label="Documentation" class="flex w-64 shrink-0 flex-col overflow-y-auto border-r border-tsm16-line bg-tsm16-surface">
    <div class="flex items-center gap-2.5 border-b border-tsm16-line px-4 py-[18px]">
      <span aria-hidden="true" class="grid size-8 place-items-center rounded-lg bg-tsm16-acc text-sm font-extrabold text-white">D</span>
      <p class="text-sm font-extrabold">DocBase <span class="ml-1 text-[10px] font-medium text-tsm16-mut2">v3.2</span></p>
    </div>
    <div class="border-b border-tsm16-line px-3.5 py-2.5">
      <label class="flex min-h-10 items-center gap-2 rounded-lg border border-tsm16-line bg-tsm16-bg px-3 text-tsm16-mut2 focus-within:border-tsm16-acc2 focus-within:ring-3 focus-within:ring-tsm16-acc/15">
        <svg class="size-4 shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="11" cy="11" r="7"/><path d="m20 20-3.5-3.5"/></svg>
        <span class="sr-only">Search documentation</span>
        <input type="search" placeholder="Search docs…" class="min-w-0 flex-1 bg-transparent text-xs text-tsm16-ink outline-none placeholder:text-tsm16-mut2">
        <kbd class="rounded border border-tsm16-line bg-tsm16-surface px-1.5 font-tsm16-mono text-[10px] text-tsm16-mut2">⌘K</kbd>
      </label>
    </div>
    <a href="#" class="flex min-h-11 items-center gap-2.5 border-b border-tsm16-line px-4 text-[13px] font-semibold text-tsm16-mut2 transition-colors hover:bg-tsm16-acc/4 hover:text-tsm16-acc focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tsm16-acc"><svg class="size-4 shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 10.5 12 3l9 7.5"/><path d="M5 9.5V20h14V9.5"/><path d="M10 20v-6h4v6"/></svg>Overview</a>
    <div class="group/sec border-b border-tsm16-line">
      <input type="checkbox" id="tsm-16-a1" class="sr-only" checked>
      <label for="tsm-16-a1" class="flex min-h-11 cursor-pointer items-center gap-2.5 px-4 text-xs font-bold tracking-[0.1em] text-tsm16-mut2 uppercase select-none transition-colors hover:bg-tsm16-acc/4 group-has-checked/sec:text-tsm16-acc group-has-[input:focus-visible]/sec:outline-2 group-has-[input:focus-visible]/sec:-outline-offset-2 group-has-[input:focus-visible]/sec:outline-tsm16-acc"><svg class="size-4 shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 15c-1.5 1.3-2 5-2 5s3.7-.5 5-2"/><path d="M9 15l-3-3c1.5-4 5-8.5 12-9-.5 7-5 10.5-9 12z"/><circle cx="14.5" cy="9.5" r="1.5"/></svg>Getting started<svg class="ml-auto size-3.5 shrink-0 transition-transform duration-300 group-has-checked/sec:rotate-90 motion-reduce:transition-none" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m9 6 6 6-6 6"/></svg></label>
      <div class="grid grid-rows-[0fr] transition-[grid-template-rows] duration-350 ease-[cubic-bezier(0.4,0,0.2,1)] group-has-checked/sec:grid-rows-[1fr] motion-reduce:transition-none">
        <ul class="invisible min-h-0 overflow-hidden pb-0 transition-[visibility] duration-350 group-has-checked/sec:visible group-has-checked/sec:pb-2"><li><a href="#" class="relative flex min-h-10 items-center gap-2.5 py-2 pr-4 pl-9 text-[13px] font-semibold text-tsm16-mut2 transition-colors before:absolute before:top-1/2 before:left-5 before:size-1 before:-translate-y-1/2 before:rounded-full before:bg-tsm16-mut before:transition-[background-color,scale] hover:bg-tsm16-acc/5 hover:text-tsm16-acc hover:before:scale-150 hover:before:bg-tsm16-acc focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tsm16-acc aria-[current=page]:bg-tsm16-acc/7 aria-[current=page]:text-tsm16-acc aria-[current=page]:before:bg-tsm16-acc" aria-current="page">Installation</a></li><li><a href="#" class="relative flex min-h-10 items-center gap-2.5 py-2 pr-4 pl-9 text-[13px] font-semibold text-tsm16-mut2 transition-colors before:absolute before:top-1/2 before:left-5 before:size-1 before:-translate-y-1/2 before:rounded-full before:bg-tsm16-mut before:transition-[background-color,scale] hover:bg-tsm16-acc/5 hover:text-tsm16-acc hover:before:scale-150 hover:before:bg-tsm16-acc focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tsm16-acc aria-[current=page]:bg-tsm16-acc/7 aria-[current=page]:text-tsm16-acc aria-[current=page]:before:bg-tsm16-acc">Configuration</a></li><li><a href="#" class="relative flex min-h-10 items-center gap-2.5 py-2 pr-4 pl-9 text-[13px] font-semibold text-tsm16-mut2 transition-colors before:absolute before:top-1/2 before:left-5 before:size-1 before:-translate-y-1/2 before:rounded-full before:bg-tsm16-mut before:transition-[background-color,scale] hover:bg-tsm16-acc/5 hover:text-tsm16-acc hover:before:scale-150 hover:before:bg-tsm16-acc focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tsm16-acc aria-[current=page]:bg-tsm16-acc/7 aria-[current=page]:text-tsm16-acc aria-[current=page]:before:bg-tsm16-acc">Quick start</a></li><li><a href="#" class="relative flex min-h-10 items-center gap-2.5 py-2 pr-4 pl-9 text-[13px] font-semibold text-tsm16-mut2 transition-colors before:absolute before:top-1/2 before:left-5 before:size-1 before:-translate-y-1/2 before:rounded-full before:bg-tsm16-mut before:transition-[background-color,scale] hover:bg-tsm16-acc/5 hover:text-tsm16-acc hover:before:scale-150 hover:before:bg-tsm16-acc focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tsm16-acc aria-[current=page]:bg-tsm16-acc/7 aria-[current=page]:text-tsm16-acc aria-[current=page]:before:bg-tsm16-acc">Examples</a></li></ul>
      </div>
    </div>
    <div class="group/sec border-b border-tsm16-line">
      <input type="checkbox" id="tsm-16-a2" class="sr-only">
      <label for="tsm-16-a2" class="flex min-h-11 cursor-pointer items-center gap-2.5 px-4 text-xs font-bold tracking-[0.1em] text-tsm16-mut2 uppercase select-none transition-colors hover:bg-tsm16-acc/4 group-has-checked/sec:text-tsm16-acc group-has-[input:focus-visible]/sec:outline-2 group-has-[input:focus-visible]/sec:-outline-offset-2 group-has-[input:focus-visible]/sec:outline-tsm16-acc"><svg class="size-4 shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m12 3 9 5-9 5-9-5z"/><path d="m3 13 9 5 9-5"/></svg>Core concepts<svg class="ml-auto size-3.5 shrink-0 transition-transform duration-300 group-has-checked/sec:rotate-90 motion-reduce:transition-none" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m9 6 6 6-6 6"/></svg></label>
      <div class="grid grid-rows-[0fr] transition-[grid-template-rows] duration-350 ease-[cubic-bezier(0.4,0,0.2,1)] group-has-checked/sec:grid-rows-[1fr] motion-reduce:transition-none">
        <ul class="invisible min-h-0 overflow-hidden pb-0 transition-[visibility] duration-350 group-has-checked/sec:visible group-has-checked/sec:pb-2"><li><a href="#" class="relative flex min-h-10 items-center gap-2.5 py-2 pr-4 pl-9 text-[13px] font-semibold text-tsm16-mut2 transition-colors before:absolute before:top-1/2 before:left-5 before:size-1 before:-translate-y-1/2 before:rounded-full before:bg-tsm16-mut before:transition-[background-color,scale] hover:bg-tsm16-acc/5 hover:text-tsm16-acc hover:before:scale-150 hover:before:bg-tsm16-acc focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tsm16-acc aria-[current=page]:bg-tsm16-acc/7 aria-[current=page]:text-tsm16-acc aria-[current=page]:before:bg-tsm16-acc">Architecture</a></li><li><a href="#" class="relative flex min-h-10 items-center gap-2.5 py-2 pr-4 pl-9 text-[13px] font-semibold text-tsm16-mut2 transition-colors before:absolute before:top-1/2 before:left-5 before:size-1 before:-translate-y-1/2 before:rounded-full before:bg-tsm16-mut before:transition-[background-color,scale] hover:bg-tsm16-acc/5 hover:text-tsm16-acc hover:before:scale-150 hover:before:bg-tsm16-acc focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tsm16-acc aria-[current=page]:bg-tsm16-acc/7 aria-[current=page]:text-tsm16-acc aria-[current=page]:before:bg-tsm16-acc">Data flow</a></li><li><a href="#" class="relative flex min-h-10 items-center gap-2.5 py-2 pr-4 pl-9 text-[13px] font-semibold text-tsm16-mut2 transition-colors before:absolute before:top-1/2 before:left-5 before:size-1 before:-translate-y-1/2 before:rounded-full before:bg-tsm16-mut before:transition-[background-color,scale] hover:bg-tsm16-acc/5 hover:text-tsm16-acc hover:before:scale-150 hover:before:bg-tsm16-acc focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tsm16-acc aria-[current=page]:bg-tsm16-acc/7 aria-[current=page]:text-tsm16-acc aria-[current=page]:before:bg-tsm16-acc">State management</a></li><li><a href="#" class="relative flex min-h-10 items-center gap-2.5 py-2 pr-4 pl-9 text-[13px] font-semibold text-tsm16-mut2 transition-colors before:absolute before:top-1/2 before:left-5 before:size-1 before:-translate-y-1/2 before:rounded-full before:bg-tsm16-mut before:transition-[background-color,scale] hover:bg-tsm16-acc/5 hover:text-tsm16-acc hover:before:scale-150 hover:before:bg-tsm16-acc focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tsm16-acc aria-[current=page]:bg-tsm16-acc/7 aria-[current=page]:text-tsm16-acc aria-[current=page]:before:bg-tsm16-acc">Routing</a></li></ul>
      </div>
    </div>
    <div class="group/sec border-b border-tsm16-line">
      <input type="checkbox" id="tsm-16-a3" class="sr-only">
      <label for="tsm-16-a3" class="flex min-h-11 cursor-pointer items-center gap-2.5 px-4 text-xs font-bold tracking-[0.1em] text-tsm16-mut2 uppercase select-none transition-colors hover:bg-tsm16-acc/4 group-has-checked/sec:text-tsm16-acc group-has-[input:focus-visible]/sec:outline-2 group-has-[input:focus-visible]/sec:-outline-offset-2 group-has-[input:focus-visible]/sec:outline-tsm16-acc"><svg class="size-4 shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m8 8-4 4 4 4"/><path d="m16 8 4 4-4 4"/></svg>API reference<svg class="ml-auto size-3.5 shrink-0 transition-transform duration-300 group-has-checked/sec:rotate-90 motion-reduce:transition-none" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m9 6 6 6-6 6"/></svg></label>
      <div class="grid grid-rows-[0fr] transition-[grid-template-rows] duration-350 ease-[cubic-bezier(0.4,0,0.2,1)] group-has-checked/sec:grid-rows-[1fr] motion-reduce:transition-none">
        <ul class="invisible min-h-0 overflow-hidden pb-0 transition-[visibility] duration-350 group-has-checked/sec:visible group-has-checked/sec:pb-2"><li><a href="#" class="relative flex min-h-10 items-center gap-2.5 py-2 pr-4 pl-9 text-[13px] font-semibold text-tsm16-mut2 transition-colors before:absolute before:top-1/2 before:left-5 before:size-1 before:-translate-y-1/2 before:rounded-full before:bg-tsm16-mut before:transition-[background-color,scale] hover:bg-tsm16-acc/5 hover:text-tsm16-acc hover:before:scale-150 hover:before:bg-tsm16-acc focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tsm16-acc aria-[current=page]:bg-tsm16-acc/7 aria-[current=page]:text-tsm16-acc aria-[current=page]:before:bg-tsm16-acc">Endpoints<span class="ml-auto rounded-full bg-tsm16-acc/12 px-1.5 text-[10px] font-bold text-tsm16-acc">48</span></a></li><li><a href="#" class="relative flex min-h-10 items-center gap-2.5 py-2 pr-4 pl-9 text-[13px] font-semibold text-tsm16-mut2 transition-colors before:absolute before:top-1/2 before:left-5 before:size-1 before:-translate-y-1/2 before:rounded-full before:bg-tsm16-mut before:transition-[background-color,scale] hover:bg-tsm16-acc/5 hover:text-tsm16-acc hover:before:scale-150 hover:before:bg-tsm16-acc focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tsm16-acc aria-[current=page]:bg-tsm16-acc/7 aria-[current=page]:text-tsm16-acc aria-[current=page]:before:bg-tsm16-acc">Authentication</a></li><li><a href="#" class="relative flex min-h-10 items-center gap-2.5 py-2 pr-4 pl-9 text-[13px] font-semibold text-tsm16-mut2 transition-colors before:absolute before:top-1/2 before:left-5 before:size-1 before:-translate-y-1/2 before:rounded-full before:bg-tsm16-mut before:transition-[background-color,scale] hover:bg-tsm16-acc/5 hover:text-tsm16-acc hover:before:scale-150 hover:before:bg-tsm16-acc focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tsm16-acc aria-[current=page]:bg-tsm16-acc/7 aria-[current=page]:text-tsm16-acc aria-[current=page]:before:bg-tsm16-acc">Webhooks</a></li><li><a href="#" class="relative flex min-h-10 items-center gap-2.5 py-2 pr-4 pl-9 text-[13px] font-semibold text-tsm16-mut2 transition-colors before:absolute before:top-1/2 before:left-5 before:size-1 before:-translate-y-1/2 before:rounded-full before:bg-tsm16-mut before:transition-[background-color,scale] hover:bg-tsm16-acc/5 hover:text-tsm16-acc hover:before:scale-150 hover:before:bg-tsm16-acc focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tsm16-acc aria-[current=page]:bg-tsm16-acc/7 aria-[current=page]:text-tsm16-acc aria-[current=page]:before:bg-tsm16-acc">Rate limits</a></li></ul>
      </div>
    </div>
    <div class="group/sec border-b border-tsm16-line">
      <input type="checkbox" id="tsm-16-a4" class="sr-only">
      <label for="tsm-16-a4" class="flex min-h-11 cursor-pointer items-center gap-2.5 px-4 text-xs font-bold tracking-[0.1em] text-tsm16-mut2 uppercase select-none transition-colors hover:bg-tsm16-acc/4 group-has-checked/sec:text-tsm16-acc group-has-[input:focus-visible]/sec:outline-2 group-has-[input:focus-visible]/sec:-outline-offset-2 group-has-[input:focus-visible]/sec:outline-tsm16-acc"><svg class="size-4 shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 19a2 2 0 0 1 2-2h14V3H6a2 2 0 0 0-2 2z"/><path d="M4 19a2 2 0 0 0 2 2h14v-4"/></svg>Guides<svg class="ml-auto size-3.5 shrink-0 transition-transform duration-300 group-has-checked/sec:rotate-90 motion-reduce:transition-none" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m9 6 6 6-6 6"/></svg></label>
      <div class="grid grid-rows-[0fr] transition-[grid-template-rows] duration-350 ease-[cubic-bezier(0.4,0,0.2,1)] group-has-checked/sec:grid-rows-[1fr] motion-reduce:transition-none">
        <ul class="invisible min-h-0 overflow-hidden pb-0 transition-[visibility] duration-350 group-has-checked/sec:visible group-has-checked/sec:pb-2"><li><a href="#" class="relative flex min-h-10 items-center gap-2.5 py-2 pr-4 pl-9 text-[13px] font-semibold text-tsm16-mut2 transition-colors before:absolute before:top-1/2 before:left-5 before:size-1 before:-translate-y-1/2 before:rounded-full before:bg-tsm16-mut before:transition-[background-color,scale] hover:bg-tsm16-acc/5 hover:text-tsm16-acc hover:before:scale-150 hover:before:bg-tsm16-acc focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tsm16-acc aria-[current=page]:bg-tsm16-acc/7 aria-[current=page]:text-tsm16-acc aria-[current=page]:before:bg-tsm16-acc">Deployment</a></li><li><a href="#" class="relative flex min-h-10 items-center gap-2.5 py-2 pr-4 pl-9 text-[13px] font-semibold text-tsm16-mut2 transition-colors before:absolute before:top-1/2 before:left-5 before:size-1 before:-translate-y-1/2 before:rounded-full before:bg-tsm16-mut before:transition-[background-color,scale] hover:bg-tsm16-acc/5 hover:text-tsm16-acc hover:before:scale-150 hover:before:bg-tsm16-acc focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tsm16-acc aria-[current=page]:bg-tsm16-acc/7 aria-[current=page]:text-tsm16-acc aria-[current=page]:before:bg-tsm16-acc">Performance</a></li><li><a href="#" class="relative flex min-h-10 items-center gap-2.5 py-2 pr-4 pl-9 text-[13px] font-semibold text-tsm16-mut2 transition-colors before:absolute before:top-1/2 before:left-5 before:size-1 before:-translate-y-1/2 before:rounded-full before:bg-tsm16-mut before:transition-[background-color,scale] hover:bg-tsm16-acc/5 hover:text-tsm16-acc hover:before:scale-150 hover:before:bg-tsm16-acc focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tsm16-acc aria-[current=page]:bg-tsm16-acc/7 aria-[current=page]:text-tsm16-acc aria-[current=page]:before:bg-tsm16-acc">Security</a></li></ul>
      </div>
    </div>
    <a href="#" class="flex min-h-11 items-center gap-2.5 border-b border-tsm16-line px-4 text-[13px] font-semibold text-tsm16-mut2 transition-colors hover:bg-tsm16-acc/4 hover:text-tsm16-acc focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tsm16-acc"><svg class="size-4 shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M14 3H6v18h12V7z"/><path d="M14 3v4h4"/><path d="M9 13h6M9 17h6"/></svg>Changelog</a>
  </nav>
  <div class="min-w-0 flex-1 p-6">
    <div class="mx-auto max-w-2xl">
      <h1 class="text-xl font-extrabold">Documentation</h1>
      <p class="mt-1.5 mb-6 max-w-prose text-[13px] leading-relaxed text-tsm16-mut2 text-pretty">Each sidebar section is a hidden checkbox and a <code class="rounded bg-tsm16-acc/8 px-1 font-tsm16-mono text-[12px] text-tsm16-acc">grid-rows-[0fr]</code> → <code class="rounded bg-tsm16-acc/8 px-1 font-tsm16-mono text-[12px] text-tsm16-acc">[1fr]</code> transition, so it opens to its real height.</p>
      <div class="grid gap-2.5">
        <a href="#" class="group/c flex items-center gap-3 rounded-xl border border-tsm16-line bg-tsm16-surface px-4 py-3.5 transition-[border-color,box-shadow,translate] hover:-translate-y-px hover:border-tsm16-acc2 hover:shadow-[0_4px_16px_oklch(0.55_0.2_262/0.1)] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tsm16-acc"><span class="grid size-9 shrink-0 place-items-center rounded-lg bg-tsm16-acc/8 text-tsm16-acc"><svg class="size-[18px] shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 4v11"/><path d="m7 10 5 5 5-5"/><path d="M5 20h14"/></svg></span><span class="min-w-0"><span class="block text-[13px] font-bold">Installation guide</span><span class="block text-xs text-tsm16-mut2">Set up your environment in under five minutes</span></span><svg class="ml-auto size-4 shrink-0 text-tsm16-mut transition-[translate,color] group-hover/c:translate-x-0.5 group-hover/c:text-tsm16-acc" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m9 6 6 6-6 6"/></svg></a>
        <a href="#" class="group/c flex items-center gap-3 rounded-xl border border-tsm16-line bg-tsm16-surface px-4 py-3.5 transition-[border-color,box-shadow,translate] hover:-translate-y-px hover:border-tsm16-acc2 hover:shadow-[0_4px_16px_oklch(0.55_0.2_262/0.1)] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tsm16-acc"><span class="grid size-9 shrink-0 place-items-center rounded-lg bg-tsm16-acc/8 text-tsm16-acc"><svg class="size-[18px] shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 6h9"/><path d="M19 6h1"/><circle cx="16" cy="6" r="2.5"/><path d="M4 12h2"/><path d="M12 12h8"/><circle cx="9" cy="12" r="2.5"/><path d="M4 18h11"/><circle cx="18" cy="18" r="2.5"/></svg></span><span class="min-w-0"><span class="block text-[13px] font-bold">Configuration reference</span><span class="block text-xs text-tsm16-mut2">Every option, with examples</span></span><svg class="ml-auto size-4 shrink-0 text-tsm16-mut transition-[translate,color] group-hover/c:translate-x-0.5 group-hover/c:text-tsm16-acc" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m9 6 6 6-6 6"/></svg></a>
        <a href="#" class="group/c flex items-center gap-3 rounded-xl border border-tsm16-line bg-tsm16-surface px-4 py-3.5 transition-[border-color,box-shadow,translate] hover:-translate-y-px hover:border-tsm16-acc2 hover:shadow-[0_4px_16px_oklch(0.55_0.2_262/0.1)] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tsm16-acc"><span class="grid size-9 shrink-0 place-items-center rounded-lg bg-tsm16-acc/8 text-tsm16-acc"><svg class="size-[18px] shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M13 2 4 14h7l-1 8 9-12h-7z"/></svg></span><span class="min-w-0"><span class="block text-[13px] font-bold">Quick-start tutorial</span><span class="block text-xs text-tsm16-mut2">Build your first integration in ten steps</span></span><svg class="ml-auto size-4 shrink-0 text-tsm16-mut transition-[translate,color] group-hover/c:translate-x-0.5 group-hover/c:text-tsm16-acc" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m9 6 6 6-6 6"/></svg></a>
      </div>
    </div>
  </div>
</section>
```
## CSS
```css
@import "tailwindcss";

@theme {
  --color-tsm16-bg: #f0f4ff;
  --color-tsm16-bg: oklch(0.967 0.015 270);
  --color-tsm16-surface: #ffffff;
  --color-tsm16-surface: oklch(1 0 0);
  --color-tsm16-line: #e2e8f0;
  --color-tsm16-line: oklch(0.929 0.013 255.5);
  --color-tsm16-acc: #2563eb;
  --color-tsm16-acc: oklch(0.546 0.215 262.9);
  --color-tsm16-acc2: #60a5fa;
  --color-tsm16-acc2: oklch(0.714 0.143 254.6);
  --color-tsm16-ink: #0f172a;
  --color-tsm16-ink: oklch(0.208 0.04 265.8);
  --color-tsm16-mut: #94a3b8;
  --color-tsm16-mut: oklch(0.711 0.035 256.8);
  --color-tsm16-mut2: #526075;
  --color-tsm16-mut2: oklch(0.485 0.038 258.4);
  --font-tsm16-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
  --font-tsm16-mono: 'JetBrains Mono', ui-monospace, monospace;
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's utilities, so the
   stage is sized before the browser build compiles. */

.tsm-16 {
  width: 100%;
  min-height: 100svh;
}
```

How this works

The 0fr → 1fr trick. A single-row grid whose track transitions from 0fr to 1fr grows to exactly its content's height. The child needs min-h-0 and overflow-hidden so it can shrink below its intrinsic size:

<div class="group/sec">
  <input type="checkbox" class="sr-only">
  <label>Getting started</label>
  <div class="grid grid-rows-[0fr] transition-[grid-template-rows]
    group-has-checked/sec:grid-rows-[1fr]">
    <ul class="min-h-0 overflow-hidden">

One group name, many sections. Every section is group/sec; a group-*/sec: variant resolves against the nearest matching ancestor, so sections never react to each other.

Keyboard-ready. The checkbox is sr-only; Tab focuses it, Space toggles it, and group-has-[input:focus-visible]/sec: draws the ring on the visible header.

Make it yours

  • Exclusive sections: switch to type="radio" inputs sharing one name.
  • Pre-open a section with the checked attribute.
  • Live filtering needs a few lines of JS on the search field — the accordion CSS stays as is.
  • Indent deeper levels by increasing pl-9 and the before:left-5 dot offset together.

Gotchas — read before shipping

  • Forget min-h-0 on the grid child and the row never collapses below the content height.
  • Checkboxes inside a <form> are submitted — leave them unnamed.
  • grid-template-rows transitions need Chrome 107 / Safari 16 / Firefox 66; older engines toggle instantly.

Browser support

ChromeSafariFirefoxEdge
111+16.4+128+111+

Animatable grid-template-rows and :has() are inside v4's own browser floor.

Techniques used in this demo

Utilitiesfirst-class utility or variant

Search CodeFronts

Loading…