01 / 17
All 17 in 17 Tailwind CSS Side Menus
- 01Tailwind Slide-In Side Menu with Animated Hamburger Icon
- 02Tailwind Sidebar Drawer with Blurred Backdrop Overlay
- 03Tailwind Off-Canvas Push Sidebar Menu
- 04Tailwind Collapsible Icon Sidebar That Expands on Hover
- 05Responsive Tailwind Sidebar with Mobile Hamburger Toggle
- 06Tailwind Sticky Sidebar Navigation with Scrolling Content
- 07Tailwind Multi-Level Dropdown Sidebar Menu (Nested Accordion)
- 08Tailwind Full-Height Flexbox Sidebar Layout
- 09Tailwind Neumorphism Sidebar Menu (Dark Mode)
- 10Tailwind Glassmorphism Sidebar with Backdrop Blur
- 11Tailwind Cyberpunk Neon Sidebar (Dark Mode)
- 12Brutalist Sidebar Navigation in Tailwind CSS
- 13Pure CSS Hamburger Menu in Tailwind (Checkbox Hack, No JS)
- 14Tailwind Sidebar Drawer That Opens on Hover
- 15Tailwind Collapsible Sidebar with Toggle Button (No JS)
- 16Tailwind Accordion Sidebar Navigation for Documentation
- 17Tailwind macOS-Style Glass Dock Sidebar with Sliding Highlight
Tailwind Slide-In Side Menu with Animated Hamburger Icon
A navigation drawer that slides in from the left when the hamburger is pressed, with the three bars morphing into an ✕ and each link easing in on a stagger. The whole state machine is one visually hidden checkbox read by v4's group-has-checked: variant — so the drawer, the icon, the scrim and the link cascade all hang off the root. Zero JavaScript.
Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time
Untitled UI React · Affiliate link
The code
<section class="tsm-01 group relative isolate w-full min-h-svh overflow-hidden bg-tsm01-bg bg-[radial-gradient(80%_60%_at_100%_0%,var(--color-tsm01-glow),transparent_70%)] font-tsm01-sans text-tsm01-ink" aria-label="Slide-in side menu demo">
<input type="checkbox" id="tsm-01-toggle" class="peer sr-only">
<label for="tsm-01-toggle" data-tsm01-burger class="absolute top-5 left-5 z-50 grid size-11 cursor-pointer place-content-center gap-[5px] rounded-xl border border-tsm01-acc/30 bg-tsm01-surface transition-colors hover:border-tsm01-acc hover:bg-tsm01-acc peer-focus-visible:outline-2 peer-focus-visible:outline-offset-2 peer-focus-visible:outline-tsm01-acc2">
<span class="sr-only">Toggle navigation menu</span>
<span aria-hidden="true" class="block h-0.5 w-5 rounded-full bg-tsm01-ink transition-transform duration-400 group-has-checked:translate-y-[7px] group-has-checked:rotate-45 motion-reduce:transition-none"></span>
<span aria-hidden="true" class="block h-0.5 w-5 rounded-full bg-tsm01-ink transition-[opacity,scale] duration-400 group-has-checked:scale-x-0 group-has-checked:opacity-0 motion-reduce:transition-none"></span>
<span aria-hidden="true" class="block h-0.5 w-5 rounded-full bg-tsm01-ink transition-transform duration-400 group-has-checked:-translate-y-[7px] group-has-checked:-rotate-45 motion-reduce:transition-none"></span>
</label>
<label for="tsm-01-toggle" aria-hidden="true" class="pointer-events-none absolute inset-0 z-30 bg-black/0 transition-colors duration-400 group-has-checked:pointer-events-auto group-has-checked:bg-black/45"></label>
<nav aria-label="Main" class="invisible absolute inset-y-0 left-0 z-40 flex w-[min(280px,86vw)] -translate-x-full flex-col border-r border-tsm01-acc/20 bg-tsm01-menu pt-20 pb-6 shadow-[8px_0_40px_oklch(0_0_0/0.45)] transition-[translate,visibility] duration-400 ease-[cubic-bezier(0.4,0,0.2,1)] group-has-checked:visible group-has-checked:translate-x-0 motion-reduce:transition-none">
<div class="mx-6 mb-4 flex items-center gap-3 border-b border-tsm01-acc/20 pb-5">
<span aria-hidden="true" class="grid size-9 place-items-center rounded-[10px] bg-linear-135 from-tsm01-acc to-tsm01-acc2 font-bold">V</span>
<div><p class="font-bold">Velocity</p><p class="text-[11px] text-tsm01-mut">Design System</p></div>
</div>
<ul class="grid flex-1 content-start gap-1 px-3">
<li class="opacity-0 -translate-x-3 transition-[opacity,translate] duration-300 group-has-checked:translate-x-0 group-has-checked:opacity-100 group-has-checked:delay-[80ms] motion-reduce:transition-none"><a href="#" class="group/l flex min-h-11 items-center gap-3 rounded-xl px-3 text-sm font-medium text-tsm01-mut transition-colors hover:bg-tsm01-acc/15 hover:text-tsm01-ink focus-visible:outline-2 focus-visible:outline-tsm01-acc2 aria-[current=page]:bg-tsm01-acc/20 aria-[current=page]:text-tsm01-ink" aria-current="page"><span class="grid size-9 place-items-center rounded-lg bg-white/5 transition-colors group-hover/l:bg-tsm01-acc group-aria-[current=page]/l:bg-tsm01-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"><rect x="3" y="3" width="7" height="7" rx="1.5"/><rect x="14" y="3" width="7" height="7" rx="1.5"/><rect x="3" y="14" width="7" height="7" rx="1.5"/><rect x="14" y="14" width="7" height="7" rx="1.5"/></svg></span>Dashboard</a></li>
<li class="opacity-0 -translate-x-3 transition-[opacity,translate] duration-300 group-has-checked:translate-x-0 group-has-checked:opacity-100 group-has-checked:delay-[125ms] motion-reduce:transition-none"><a href="#" class="group/l flex min-h-11 items-center gap-3 rounded-xl px-3 text-sm font-medium text-tsm01-mut transition-colors hover:bg-tsm01-acc/15 hover:text-tsm01-ink focus-visible:outline-2 focus-visible:outline-tsm01-acc2 aria-[current=page]:bg-tsm01-acc/20 aria-[current=page]:text-tsm01-ink"><span class="grid size-9 place-items-center rounded-lg bg-white/5 transition-colors group-hover/l:bg-tsm01-acc group-aria-[current=page]/l:bg-tsm01-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="M3 3v18h18"/><path d="m7 15 4-4 3 3 5-6"/></svg></span>Analytics</a></li>
<li class="opacity-0 -translate-x-3 transition-[opacity,translate] duration-300 group-has-checked:translate-x-0 group-has-checked:opacity-100 group-has-checked:delay-[170ms] motion-reduce:transition-none"><a href="#" class="group/l flex min-h-11 items-center gap-3 rounded-xl px-3 text-sm font-medium text-tsm01-mut transition-colors hover:bg-tsm01-acc/15 hover:text-tsm01-ink focus-visible:outline-2 focus-visible:outline-tsm01-acc2 aria-[current=page]:bg-tsm01-acc/20 aria-[current=page]:text-tsm01-ink"><span class="grid size-9 place-items-center rounded-lg bg-white/5 transition-colors group-hover/l:bg-tsm01-acc group-aria-[current=page]/l:bg-tsm01-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="M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/></svg></span>Projects</a></li>
<li class="opacity-0 -translate-x-3 transition-[opacity,translate] duration-300 group-has-checked:translate-x-0 group-has-checked:opacity-100 group-has-checked:delay-[215ms] motion-reduce:transition-none"><a href="#" class="group/l flex min-h-11 items-center gap-3 rounded-xl px-3 text-sm font-medium text-tsm01-mut transition-colors hover:bg-tsm01-acc/15 hover:text-tsm01-ink focus-visible:outline-2 focus-visible:outline-tsm01-acc2 aria-[current=page]:bg-tsm01-acc/20 aria-[current=page]:text-tsm01-ink"><span class="grid size-9 place-items-center rounded-lg bg-white/5 transition-colors group-hover/l:bg-tsm01-acc group-aria-[current=page]/l:bg-tsm01-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="M21 12a8 8 0 0 1-11.6 7.1L4 20l1-4.6A8 8 0 1 1 21 12z"/></svg></span>Messages</a></li>
<li class="opacity-0 -translate-x-3 transition-[opacity,translate] duration-300 group-has-checked:translate-x-0 group-has-checked:opacity-100 group-has-checked:delay-[260ms] motion-reduce:transition-none"><a href="#" class="group/l flex min-h-11 items-center gap-3 rounded-xl px-3 text-sm font-medium text-tsm01-mut transition-colors hover:bg-tsm01-acc/15 hover:text-tsm01-ink focus-visible:outline-2 focus-visible:outline-tsm01-acc2 aria-[current=page]:bg-tsm01-acc/20 aria-[current=page]:text-tsm01-ink"><span class="grid size-9 place-items-center rounded-lg bg-white/5 transition-colors group-hover/l:bg-tsm01-acc group-aria-[current=page]/l:bg-tsm01-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>Settings</a></li>
</ul>
<div class="mx-6 flex items-center gap-3 border-t border-tsm01-acc/20 pt-4">
<span aria-hidden="true" class="grid size-9 place-items-center rounded-full bg-linear-135 from-amber-500 to-red-500 text-[13px] font-bold">JD</span>
<div><p class="text-[13px] font-semibold">Jane Doe</p><p class="text-[11px] text-tsm01-mut">Pro plan</p></div>
</div>
</nav>
<div class="mx-auto w-full max-w-3xl px-6 pt-24 pb-10">
<h1 class="text-[clamp(22px,3vw,28px)] font-bold tracking-tight">Welcome back, Jane</h1>
<p class="mt-2 mb-7 max-w-prose text-sm leading-relaxed text-tsm01-mut text-pretty">Press the menu button to slide the drawer in. Click the dimmed page or press the button again to close it.</p>
<div class="grid grid-cols-2 gap-3 md:grid-cols-4">
<div class="rounded-2xl border border-tsm01-acc/20 bg-tsm01-surface p-4"><p class="text-2xl font-bold tabular-nums text-tsm01-acc2">2,847</p><p class="mt-1 text-xs text-tsm01-mut">Page views</p></div>
<div class="rounded-2xl border border-tsm01-acc/20 bg-tsm01-surface p-4"><p class="text-2xl font-bold tabular-nums text-tsm01-acc2">94%</p><p class="mt-1 text-xs text-tsm01-mut">Uptime</p></div>
<div class="rounded-2xl border border-tsm01-acc/20 bg-tsm01-surface p-4"><p class="text-2xl font-bold tabular-nums text-tsm01-acc2">$12.4k</p><p class="mt-1 text-xs text-tsm01-mut">Revenue</p></div>
<div class="rounded-2xl border border-tsm01-acc/20 bg-tsm01-surface p-4"><p class="text-2xl font-bold tabular-nums text-tsm01-acc2">483</p><p class="mt-1 text-xs text-tsm01-mut">Users</p></div>
</div>
</div>
</section><section class="tsm-01 group relative isolate w-full min-h-svh overflow-hidden bg-tsm01-bg bg-[radial-gradient(80%_60%_at_100%_0%,var(--color-tsm01-glow),transparent_70%)] font-tsm01-sans text-tsm01-ink" aria-label="Slide-in side menu demo">
<input type="checkbox" id="tsm-01-toggle" class="peer sr-only">
<label for="tsm-01-toggle" data-tsm01-burger class="absolute top-5 left-5 z-50 grid size-11 cursor-pointer place-content-center gap-[5px] rounded-xl border border-tsm01-acc/30 bg-tsm01-surface transition-colors hover:border-tsm01-acc hover:bg-tsm01-acc peer-focus-visible:outline-2 peer-focus-visible:outline-offset-2 peer-focus-visible:outline-tsm01-acc2">
<span class="sr-only">Toggle navigation menu</span>
<span aria-hidden="true" class="block h-0.5 w-5 rounded-full bg-tsm01-ink transition-transform duration-400 group-has-checked:translate-y-[7px] group-has-checked:rotate-45 motion-reduce:transition-none"></span>
<span aria-hidden="true" class="block h-0.5 w-5 rounded-full bg-tsm01-ink transition-[opacity,scale] duration-400 group-has-checked:scale-x-0 group-has-checked:opacity-0 motion-reduce:transition-none"></span>
<span aria-hidden="true" class="block h-0.5 w-5 rounded-full bg-tsm01-ink transition-transform duration-400 group-has-checked:-translate-y-[7px] group-has-checked:-rotate-45 motion-reduce:transition-none"></span>
</label>
<label for="tsm-01-toggle" aria-hidden="true" class="pointer-events-none absolute inset-0 z-30 bg-black/0 transition-colors duration-400 group-has-checked:pointer-events-auto group-has-checked:bg-black/45"></label>
<nav aria-label="Main" class="invisible absolute inset-y-0 left-0 z-40 flex w-[min(280px,86vw)] -translate-x-full flex-col border-r border-tsm01-acc/20 bg-tsm01-menu pt-20 pb-6 shadow-[8px_0_40px_oklch(0_0_0/0.45)] transition-[translate,visibility] duration-400 ease-[cubic-bezier(0.4,0,0.2,1)] group-has-checked:visible group-has-checked:translate-x-0 motion-reduce:transition-none">
<div class="mx-6 mb-4 flex items-center gap-3 border-b border-tsm01-acc/20 pb-5">
<span aria-hidden="true" class="grid size-9 place-items-center rounded-[10px] bg-linear-135 from-tsm01-acc to-tsm01-acc2 font-bold">V</span>
<div><p class="font-bold">Velocity</p><p class="text-[11px] text-tsm01-mut">Design System</p></div>
</div>
<ul class="grid flex-1 content-start gap-1 px-3">
<li class="opacity-0 -translate-x-3 transition-[opacity,translate] duration-300 group-has-checked:translate-x-0 group-has-checked:opacity-100 group-has-checked:delay-[80ms] motion-reduce:transition-none"><a href="#" class="group/l flex min-h-11 items-center gap-3 rounded-xl px-3 text-sm font-medium text-tsm01-mut transition-colors hover:bg-tsm01-acc/15 hover:text-tsm01-ink focus-visible:outline-2 focus-visible:outline-tsm01-acc2 aria-[current=page]:bg-tsm01-acc/20 aria-[current=page]:text-tsm01-ink" aria-current="page"><span class="grid size-9 place-items-center rounded-lg bg-white/5 transition-colors group-hover/l:bg-tsm01-acc group-aria-[current=page]/l:bg-tsm01-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"><rect x="3" y="3" width="7" height="7" rx="1.5"/><rect x="14" y="3" width="7" height="7" rx="1.5"/><rect x="3" y="14" width="7" height="7" rx="1.5"/><rect x="14" y="14" width="7" height="7" rx="1.5"/></svg></span>Dashboard</a></li>
<li class="opacity-0 -translate-x-3 transition-[opacity,translate] duration-300 group-has-checked:translate-x-0 group-has-checked:opacity-100 group-has-checked:delay-[125ms] motion-reduce:transition-none"><a href="#" class="group/l flex min-h-11 items-center gap-3 rounded-xl px-3 text-sm font-medium text-tsm01-mut transition-colors hover:bg-tsm01-acc/15 hover:text-tsm01-ink focus-visible:outline-2 focus-visible:outline-tsm01-acc2 aria-[current=page]:bg-tsm01-acc/20 aria-[current=page]:text-tsm01-ink"><span class="grid size-9 place-items-center rounded-lg bg-white/5 transition-colors group-hover/l:bg-tsm01-acc group-aria-[current=page]/l:bg-tsm01-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="M3 3v18h18"/><path d="m7 15 4-4 3 3 5-6"/></svg></span>Analytics</a></li>
<li class="opacity-0 -translate-x-3 transition-[opacity,translate] duration-300 group-has-checked:translate-x-0 group-has-checked:opacity-100 group-has-checked:delay-[170ms] motion-reduce:transition-none"><a href="#" class="group/l flex min-h-11 items-center gap-3 rounded-xl px-3 text-sm font-medium text-tsm01-mut transition-colors hover:bg-tsm01-acc/15 hover:text-tsm01-ink focus-visible:outline-2 focus-visible:outline-tsm01-acc2 aria-[current=page]:bg-tsm01-acc/20 aria-[current=page]:text-tsm01-ink"><span class="grid size-9 place-items-center rounded-lg bg-white/5 transition-colors group-hover/l:bg-tsm01-acc group-aria-[current=page]/l:bg-tsm01-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="M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/></svg></span>Projects</a></li>
<li class="opacity-0 -translate-x-3 transition-[opacity,translate] duration-300 group-has-checked:translate-x-0 group-has-checked:opacity-100 group-has-checked:delay-[215ms] motion-reduce:transition-none"><a href="#" class="group/l flex min-h-11 items-center gap-3 rounded-xl px-3 text-sm font-medium text-tsm01-mut transition-colors hover:bg-tsm01-acc/15 hover:text-tsm01-ink focus-visible:outline-2 focus-visible:outline-tsm01-acc2 aria-[current=page]:bg-tsm01-acc/20 aria-[current=page]:text-tsm01-ink"><span class="grid size-9 place-items-center rounded-lg bg-white/5 transition-colors group-hover/l:bg-tsm01-acc group-aria-[current=page]/l:bg-tsm01-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="M21 12a8 8 0 0 1-11.6 7.1L4 20l1-4.6A8 8 0 1 1 21 12z"/></svg></span>Messages</a></li>
<li class="opacity-0 -translate-x-3 transition-[opacity,translate] duration-300 group-has-checked:translate-x-0 group-has-checked:opacity-100 group-has-checked:delay-[260ms] motion-reduce:transition-none"><a href="#" class="group/l flex min-h-11 items-center gap-3 rounded-xl px-3 text-sm font-medium text-tsm01-mut transition-colors hover:bg-tsm01-acc/15 hover:text-tsm01-ink focus-visible:outline-2 focus-visible:outline-tsm01-acc2 aria-[current=page]:bg-tsm01-acc/20 aria-[current=page]:text-tsm01-ink"><span class="grid size-9 place-items-center rounded-lg bg-white/5 transition-colors group-hover/l:bg-tsm01-acc group-aria-[current=page]/l:bg-tsm01-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>Settings</a></li>
</ul>
<div class="mx-6 flex items-center gap-3 border-t border-tsm01-acc/20 pt-4">
<span aria-hidden="true" class="grid size-9 place-items-center rounded-full bg-linear-135 from-amber-500 to-red-500 text-[13px] font-bold">JD</span>
<div><p class="text-[13px] font-semibold">Jane Doe</p><p class="text-[11px] text-tsm01-mut">Pro plan</p></div>
</div>
</nav>
<div class="mx-auto w-full max-w-3xl px-6 pt-24 pb-10">
<h1 class="text-[clamp(22px,3vw,28px)] font-bold tracking-tight">Welcome back, Jane</h1>
<p class="mt-2 mb-7 max-w-prose text-sm leading-relaxed text-tsm01-mut text-pretty">Press the menu button to slide the drawer in. Click the dimmed page or press the button again to close it.</p>
<div class="grid grid-cols-2 gap-3 md:grid-cols-4">
<div class="rounded-2xl border border-tsm01-acc/20 bg-tsm01-surface p-4"><p class="text-2xl font-bold tabular-nums text-tsm01-acc2">2,847</p><p class="mt-1 text-xs text-tsm01-mut">Page views</p></div>
<div class="rounded-2xl border border-tsm01-acc/20 bg-tsm01-surface p-4"><p class="text-2xl font-bold tabular-nums text-tsm01-acc2">94%</p><p class="mt-1 text-xs text-tsm01-mut">Uptime</p></div>
<div class="rounded-2xl border border-tsm01-acc/20 bg-tsm01-surface p-4"><p class="text-2xl font-bold tabular-nums text-tsm01-acc2">$12.4k</p><p class="mt-1 text-xs text-tsm01-mut">Revenue</p></div>
<div class="rounded-2xl border border-tsm01-acc/20 bg-tsm01-surface p-4"><p class="text-2xl font-bold tabular-nums text-tsm01-acc2">483</p><p class="mt-1 text-xs text-tsm01-mut">Users</p></div>
</div>
</div>
</section>@import "tailwindcss";
@theme {
--color-tsm01-bg: #0f172a;
--color-tsm01-bg: oklch(0.208 0.04 265.8);
--color-tsm01-glow: #2a1650;
--color-tsm01-glow: oklch(0.265 0.101 294.4);
--color-tsm01-surface: #1e293b;
--color-tsm01-surface: oklch(0.279 0.037 260);
--color-tsm01-menu: #1a1033;
--color-tsm01-menu: oklch(0.209 0.066 293);
--color-tsm01-acc: #7c3aed;
--color-tsm01-acc: oklch(0.541 0.247 293);
--color-tsm01-acc2: #a78bfa;
--color-tsm01-acc2: oklch(0.709 0.159 293.5);
--color-tsm01-ink: #e2e8f0;
--color-tsm01-ink: oklch(0.929 0.013 255.5);
--color-tsm01-mut: #a3aec2;
--color-tsm01-mut: oklch(0.749 0.031 262.5);
--font-tsm01-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
/* 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-01 {
width: 100%;
min-height: 100svh;
}@import "tailwindcss";
@theme {
--color-tsm01-bg: #0f172a;
--color-tsm01-bg: oklch(0.208 0.04 265.8);
--color-tsm01-glow: #2a1650;
--color-tsm01-glow: oklch(0.265 0.101 294.4);
--color-tsm01-surface: #1e293b;
--color-tsm01-surface: oklch(0.279 0.037 260);
--color-tsm01-menu: #1a1033;
--color-tsm01-menu: oklch(0.209 0.066 293);
--color-tsm01-acc: #7c3aed;
--color-tsm01-acc: oklch(0.541 0.247 293);
--color-tsm01-acc2: #a78bfa;
--color-tsm01-acc2: oklch(0.709 0.159 293.5);
--color-tsm01-ink: #e2e8f0;
--color-tsm01-ink: oklch(0.929 0.013 255.5);
--color-tsm01-mut: #a3aec2;
--color-tsm01-mut: oklch(0.749 0.031 262.5);
--font-tsm01-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
/* 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-01 {
width: 100%;
min-height: 100svh;
}Setup — do this once per project
Skip this if your project already runs Tailwind v4.
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>Compiles in the browser — perfect for a CodePen or a quick test, not for production.
npm install tailwindcss @tailwindcss/vite
npm install tailwindcss @tailwindcss/vite// vite.config.js ("type": "module" in package.json)
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [tailwindcss()],
})// vite.config.js ("type": "module" in package.json)
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [tailwindcss()],
})Any v4 setup works — Vite, PostCSS or the CLI. Nothing in this demo is bundler-specific.
@import "tailwindcss";
@theme {
--color-tsm01-bg: #0f172a;
--color-tsm01-bg: oklch(0.208 0.04 265.8);
--color-tsm01-glow: #2a1650;
--color-tsm01-glow: oklch(0.265 0.101 294.4);
--color-tsm01-surface: #1e293b;
--color-tsm01-surface: oklch(0.279 0.037 260);
--color-tsm01-menu: #1a1033;
--color-tsm01-menu: oklch(0.209 0.066 293);
--color-tsm01-acc: #7c3aed;
--color-tsm01-acc: oklch(0.541 0.247 293);
--color-tsm01-acc2: #a78bfa;
--color-tsm01-acc2: oklch(0.709 0.159 293.5);
--color-tsm01-ink: #e2e8f0;
--color-tsm01-ink: oklch(0.929 0.013 255.5);
--color-tsm01-mut: #a3aec2;
--color-tsm01-mut: oklch(0.749 0.031 262.5);
--font-tsm01-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
/* 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-01 {
width: 100%;
min-height: 100svh;
}@import "tailwindcss";
@theme {
--color-tsm01-bg: #0f172a;
--color-tsm01-bg: oklch(0.208 0.04 265.8);
--color-tsm01-glow: #2a1650;
--color-tsm01-glow: oklch(0.265 0.101 294.4);
--color-tsm01-surface: #1e293b;
--color-tsm01-surface: oklch(0.279 0.037 260);
--color-tsm01-menu: #1a1033;
--color-tsm01-menu: oklch(0.209 0.066 293);
--color-tsm01-acc: #7c3aed;
--color-tsm01-acc: oklch(0.541 0.247 293);
--color-tsm01-acc2: #a78bfa;
--color-tsm01-acc2: oklch(0.709 0.159 293.5);
--color-tsm01-ink: #e2e8f0;
--color-tsm01-ink: oklch(0.929 0.013 255.5);
--color-tsm01-mut: #a3aec2;
--color-tsm01-mut: oklch(0.749 0.031 262.5);
--font-tsm01-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
/* 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-01 {
width: 100%;
min-height: 100svh;
}<link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap">What changed in the port
Which parts became utilities, which stayed CSS, and why.
.toggle:checked ~ .navand the three~ .burger span:nth-child()rules becamegroup-has-checked:utilities on the elements they change — the DOM-order constraint of the sibling combinator is gone.- UI upgrade from the CSS original: a click-outside scrim (a second
<label for>) dims the page and closes the drawer, and links now cascade in on a 45ms stagger. - UI upgrade: the closed drawer is
invisible, so its five links no longer sit in the tab order off-screen; the burger is 44px and shows a focus ring viapeer-focus-visible:. - UI upgrade: unicode glyphs (⬡ ◈ ⬟) were replaced with stroked SVG icons that inherit
currentColor, and muted text rose to 7.4:1.
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 Slide-In Side Menu with Animated Hamburger Icon
Source: https://codefronts.com/navigation/tailwind-css-side-menus/tailwind-slide-in-side-menu-animated-hamburger/
A navigation drawer that slides in from the left when the hamburger is pressed, with the three bars morphing into an ✕ and each link easing in on a stagger. The whole state machine is one visually hidden checkbox read by v4's group-has-checked: variant — so the drawer, the icon, the scrim and the link cascade all hang off the root. Zero JavaScript.
## HTML
```html
<section class="tsm-01 group relative isolate w-full min-h-svh overflow-hidden bg-tsm01-bg bg-[radial-gradient(80%_60%_at_100%_0%,var(--color-tsm01-glow),transparent_70%)] font-tsm01-sans text-tsm01-ink" aria-label="Slide-in side menu demo">
<input type="checkbox" id="tsm-01-toggle" class="peer sr-only">
<label for="tsm-01-toggle" data-tsm01-burger class="absolute top-5 left-5 z-50 grid size-11 cursor-pointer place-content-center gap-[5px] rounded-xl border border-tsm01-acc/30 bg-tsm01-surface transition-colors hover:border-tsm01-acc hover:bg-tsm01-acc peer-focus-visible:outline-2 peer-focus-visible:outline-offset-2 peer-focus-visible:outline-tsm01-acc2">
<span class="sr-only">Toggle navigation menu</span>
<span aria-hidden="true" class="block h-0.5 w-5 rounded-full bg-tsm01-ink transition-transform duration-400 group-has-checked:translate-y-[7px] group-has-checked:rotate-45 motion-reduce:transition-none"></span>
<span aria-hidden="true" class="block h-0.5 w-5 rounded-full bg-tsm01-ink transition-[opacity,scale] duration-400 group-has-checked:scale-x-0 group-has-checked:opacity-0 motion-reduce:transition-none"></span>
<span aria-hidden="true" class="block h-0.5 w-5 rounded-full bg-tsm01-ink transition-transform duration-400 group-has-checked:-translate-y-[7px] group-has-checked:-rotate-45 motion-reduce:transition-none"></span>
</label>
<label for="tsm-01-toggle" aria-hidden="true" class="pointer-events-none absolute inset-0 z-30 bg-black/0 transition-colors duration-400 group-has-checked:pointer-events-auto group-has-checked:bg-black/45"></label>
<nav aria-label="Main" class="invisible absolute inset-y-0 left-0 z-40 flex w-[min(280px,86vw)] -translate-x-full flex-col border-r border-tsm01-acc/20 bg-tsm01-menu pt-20 pb-6 shadow-[8px_0_40px_oklch(0_0_0/0.45)] transition-[translate,visibility] duration-400 ease-[cubic-bezier(0.4,0,0.2,1)] group-has-checked:visible group-has-checked:translate-x-0 motion-reduce:transition-none">
<div class="mx-6 mb-4 flex items-center gap-3 border-b border-tsm01-acc/20 pb-5">
<span aria-hidden="true" class="grid size-9 place-items-center rounded-[10px] bg-linear-135 from-tsm01-acc to-tsm01-acc2 font-bold">V</span>
<div><p class="font-bold">Velocity</p><p class="text-[11px] text-tsm01-mut">Design System</p></div>
</div>
<ul class="grid flex-1 content-start gap-1 px-3">
<li class="opacity-0 -translate-x-3 transition-[opacity,translate] duration-300 group-has-checked:translate-x-0 group-has-checked:opacity-100 group-has-checked:delay-[80ms] motion-reduce:transition-none"><a href="#" class="group/l flex min-h-11 items-center gap-3 rounded-xl px-3 text-sm font-medium text-tsm01-mut transition-colors hover:bg-tsm01-acc/15 hover:text-tsm01-ink focus-visible:outline-2 focus-visible:outline-tsm01-acc2 aria-[current=page]:bg-tsm01-acc/20 aria-[current=page]:text-tsm01-ink" aria-current="page"><span class="grid size-9 place-items-center rounded-lg bg-white/5 transition-colors group-hover/l:bg-tsm01-acc group-aria-[current=page]/l:bg-tsm01-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"><rect x="3" y="3" width="7" height="7" rx="1.5"/><rect x="14" y="3" width="7" height="7" rx="1.5"/><rect x="3" y="14" width="7" height="7" rx="1.5"/><rect x="14" y="14" width="7" height="7" rx="1.5"/></svg></span>Dashboard</a></li>
<li class="opacity-0 -translate-x-3 transition-[opacity,translate] duration-300 group-has-checked:translate-x-0 group-has-checked:opacity-100 group-has-checked:delay-[125ms] motion-reduce:transition-none"><a href="#" class="group/l flex min-h-11 items-center gap-3 rounded-xl px-3 text-sm font-medium text-tsm01-mut transition-colors hover:bg-tsm01-acc/15 hover:text-tsm01-ink focus-visible:outline-2 focus-visible:outline-tsm01-acc2 aria-[current=page]:bg-tsm01-acc/20 aria-[current=page]:text-tsm01-ink"><span class="grid size-9 place-items-center rounded-lg bg-white/5 transition-colors group-hover/l:bg-tsm01-acc group-aria-[current=page]/l:bg-tsm01-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="M3 3v18h18"/><path d="m7 15 4-4 3 3 5-6"/></svg></span>Analytics</a></li>
<li class="opacity-0 -translate-x-3 transition-[opacity,translate] duration-300 group-has-checked:translate-x-0 group-has-checked:opacity-100 group-has-checked:delay-[170ms] motion-reduce:transition-none"><a href="#" class="group/l flex min-h-11 items-center gap-3 rounded-xl px-3 text-sm font-medium text-tsm01-mut transition-colors hover:bg-tsm01-acc/15 hover:text-tsm01-ink focus-visible:outline-2 focus-visible:outline-tsm01-acc2 aria-[current=page]:bg-tsm01-acc/20 aria-[current=page]:text-tsm01-ink"><span class="grid size-9 place-items-center rounded-lg bg-white/5 transition-colors group-hover/l:bg-tsm01-acc group-aria-[current=page]/l:bg-tsm01-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="M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/></svg></span>Projects</a></li>
<li class="opacity-0 -translate-x-3 transition-[opacity,translate] duration-300 group-has-checked:translate-x-0 group-has-checked:opacity-100 group-has-checked:delay-[215ms] motion-reduce:transition-none"><a href="#" class="group/l flex min-h-11 items-center gap-3 rounded-xl px-3 text-sm font-medium text-tsm01-mut transition-colors hover:bg-tsm01-acc/15 hover:text-tsm01-ink focus-visible:outline-2 focus-visible:outline-tsm01-acc2 aria-[current=page]:bg-tsm01-acc/20 aria-[current=page]:text-tsm01-ink"><span class="grid size-9 place-items-center rounded-lg bg-white/5 transition-colors group-hover/l:bg-tsm01-acc group-aria-[current=page]/l:bg-tsm01-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="M21 12a8 8 0 0 1-11.6 7.1L4 20l1-4.6A8 8 0 1 1 21 12z"/></svg></span>Messages</a></li>
<li class="opacity-0 -translate-x-3 transition-[opacity,translate] duration-300 group-has-checked:translate-x-0 group-has-checked:opacity-100 group-has-checked:delay-[260ms] motion-reduce:transition-none"><a href="#" class="group/l flex min-h-11 items-center gap-3 rounded-xl px-3 text-sm font-medium text-tsm01-mut transition-colors hover:bg-tsm01-acc/15 hover:text-tsm01-ink focus-visible:outline-2 focus-visible:outline-tsm01-acc2 aria-[current=page]:bg-tsm01-acc/20 aria-[current=page]:text-tsm01-ink"><span class="grid size-9 place-items-center rounded-lg bg-white/5 transition-colors group-hover/l:bg-tsm01-acc group-aria-[current=page]/l:bg-tsm01-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>Settings</a></li>
</ul>
<div class="mx-6 flex items-center gap-3 border-t border-tsm01-acc/20 pt-4">
<span aria-hidden="true" class="grid size-9 place-items-center rounded-full bg-linear-135 from-amber-500 to-red-500 text-[13px] font-bold">JD</span>
<div><p class="text-[13px] font-semibold">Jane Doe</p><p class="text-[11px] text-tsm01-mut">Pro plan</p></div>
</div>
</nav>
<div class="mx-auto w-full max-w-3xl px-6 pt-24 pb-10">
<h1 class="text-[clamp(22px,3vw,28px)] font-bold tracking-tight">Welcome back, Jane</h1>
<p class="mt-2 mb-7 max-w-prose text-sm leading-relaxed text-tsm01-mut text-pretty">Press the menu button to slide the drawer in. Click the dimmed page or press the button again to close it.</p>
<div class="grid grid-cols-2 gap-3 md:grid-cols-4">
<div class="rounded-2xl border border-tsm01-acc/20 bg-tsm01-surface p-4"><p class="text-2xl font-bold tabular-nums text-tsm01-acc2">2,847</p><p class="mt-1 text-xs text-tsm01-mut">Page views</p></div>
<div class="rounded-2xl border border-tsm01-acc/20 bg-tsm01-surface p-4"><p class="text-2xl font-bold tabular-nums text-tsm01-acc2">94%</p><p class="mt-1 text-xs text-tsm01-mut">Uptime</p></div>
<div class="rounded-2xl border border-tsm01-acc/20 bg-tsm01-surface p-4"><p class="text-2xl font-bold tabular-nums text-tsm01-acc2">$12.4k</p><p class="mt-1 text-xs text-tsm01-mut">Revenue</p></div>
<div class="rounded-2xl border border-tsm01-acc/20 bg-tsm01-surface p-4"><p class="text-2xl font-bold tabular-nums text-tsm01-acc2">483</p><p class="mt-1 text-xs text-tsm01-mut">Users</p></div>
</div>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tsm01-bg: #0f172a;
--color-tsm01-bg: oklch(0.208 0.04 265.8);
--color-tsm01-glow: #2a1650;
--color-tsm01-glow: oklch(0.265 0.101 294.4);
--color-tsm01-surface: #1e293b;
--color-tsm01-surface: oklch(0.279 0.037 260);
--color-tsm01-menu: #1a1033;
--color-tsm01-menu: oklch(0.209 0.066 293);
--color-tsm01-acc: #7c3aed;
--color-tsm01-acc: oklch(0.541 0.247 293);
--color-tsm01-acc2: #a78bfa;
--color-tsm01-acc2: oklch(0.709 0.159 293.5);
--color-tsm01-ink: #e2e8f0;
--color-tsm01-ink: oklch(0.929 0.013 255.5);
--color-tsm01-mut: #a3aec2;
--color-tsm01-mut: oklch(0.749 0.031 262.5);
--font-tsm01-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
/* 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-01 {
width: 100%;
min-height: 100svh;
}
```Here's a working CSS demo from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Tailwind Slide-In Side Menu with Animated Hamburger Icon
Source: https://codefronts.com/navigation/tailwind-css-side-menus/tailwind-slide-in-side-menu-animated-hamburger/
A navigation drawer that slides in from the left when the hamburger is pressed, with the three bars morphing into an ✕ and each link easing in on a stagger. The whole state machine is one visually hidden checkbox read by v4's group-has-checked: variant — so the drawer, the icon, the scrim and the link cascade all hang off the root. Zero JavaScript.
## HTML
```html
<section class="tsm-01 group relative isolate w-full min-h-svh overflow-hidden bg-tsm01-bg bg-[radial-gradient(80%_60%_at_100%_0%,var(--color-tsm01-glow),transparent_70%)] font-tsm01-sans text-tsm01-ink" aria-label="Slide-in side menu demo">
<input type="checkbox" id="tsm-01-toggle" class="peer sr-only">
<label for="tsm-01-toggle" data-tsm01-burger class="absolute top-5 left-5 z-50 grid size-11 cursor-pointer place-content-center gap-[5px] rounded-xl border border-tsm01-acc/30 bg-tsm01-surface transition-colors hover:border-tsm01-acc hover:bg-tsm01-acc peer-focus-visible:outline-2 peer-focus-visible:outline-offset-2 peer-focus-visible:outline-tsm01-acc2">
<span class="sr-only">Toggle navigation menu</span>
<span aria-hidden="true" class="block h-0.5 w-5 rounded-full bg-tsm01-ink transition-transform duration-400 group-has-checked:translate-y-[7px] group-has-checked:rotate-45 motion-reduce:transition-none"></span>
<span aria-hidden="true" class="block h-0.5 w-5 rounded-full bg-tsm01-ink transition-[opacity,scale] duration-400 group-has-checked:scale-x-0 group-has-checked:opacity-0 motion-reduce:transition-none"></span>
<span aria-hidden="true" class="block h-0.5 w-5 rounded-full bg-tsm01-ink transition-transform duration-400 group-has-checked:-translate-y-[7px] group-has-checked:-rotate-45 motion-reduce:transition-none"></span>
</label>
<label for="tsm-01-toggle" aria-hidden="true" class="pointer-events-none absolute inset-0 z-30 bg-black/0 transition-colors duration-400 group-has-checked:pointer-events-auto group-has-checked:bg-black/45"></label>
<nav aria-label="Main" class="invisible absolute inset-y-0 left-0 z-40 flex w-[min(280px,86vw)] -translate-x-full flex-col border-r border-tsm01-acc/20 bg-tsm01-menu pt-20 pb-6 shadow-[8px_0_40px_oklch(0_0_0/0.45)] transition-[translate,visibility] duration-400 ease-[cubic-bezier(0.4,0,0.2,1)] group-has-checked:visible group-has-checked:translate-x-0 motion-reduce:transition-none">
<div class="mx-6 mb-4 flex items-center gap-3 border-b border-tsm01-acc/20 pb-5">
<span aria-hidden="true" class="grid size-9 place-items-center rounded-[10px] bg-linear-135 from-tsm01-acc to-tsm01-acc2 font-bold">V</span>
<div><p class="font-bold">Velocity</p><p class="text-[11px] text-tsm01-mut">Design System</p></div>
</div>
<ul class="grid flex-1 content-start gap-1 px-3">
<li class="opacity-0 -translate-x-3 transition-[opacity,translate] duration-300 group-has-checked:translate-x-0 group-has-checked:opacity-100 group-has-checked:delay-[80ms] motion-reduce:transition-none"><a href="#" class="group/l flex min-h-11 items-center gap-3 rounded-xl px-3 text-sm font-medium text-tsm01-mut transition-colors hover:bg-tsm01-acc/15 hover:text-tsm01-ink focus-visible:outline-2 focus-visible:outline-tsm01-acc2 aria-[current=page]:bg-tsm01-acc/20 aria-[current=page]:text-tsm01-ink" aria-current="page"><span class="grid size-9 place-items-center rounded-lg bg-white/5 transition-colors group-hover/l:bg-tsm01-acc group-aria-[current=page]/l:bg-tsm01-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"><rect x="3" y="3" width="7" height="7" rx="1.5"/><rect x="14" y="3" width="7" height="7" rx="1.5"/><rect x="3" y="14" width="7" height="7" rx="1.5"/><rect x="14" y="14" width="7" height="7" rx="1.5"/></svg></span>Dashboard</a></li>
<li class="opacity-0 -translate-x-3 transition-[opacity,translate] duration-300 group-has-checked:translate-x-0 group-has-checked:opacity-100 group-has-checked:delay-[125ms] motion-reduce:transition-none"><a href="#" class="group/l flex min-h-11 items-center gap-3 rounded-xl px-3 text-sm font-medium text-tsm01-mut transition-colors hover:bg-tsm01-acc/15 hover:text-tsm01-ink focus-visible:outline-2 focus-visible:outline-tsm01-acc2 aria-[current=page]:bg-tsm01-acc/20 aria-[current=page]:text-tsm01-ink"><span class="grid size-9 place-items-center rounded-lg bg-white/5 transition-colors group-hover/l:bg-tsm01-acc group-aria-[current=page]/l:bg-tsm01-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="M3 3v18h18"/><path d="m7 15 4-4 3 3 5-6"/></svg></span>Analytics</a></li>
<li class="opacity-0 -translate-x-3 transition-[opacity,translate] duration-300 group-has-checked:translate-x-0 group-has-checked:opacity-100 group-has-checked:delay-[170ms] motion-reduce:transition-none"><a href="#" class="group/l flex min-h-11 items-center gap-3 rounded-xl px-3 text-sm font-medium text-tsm01-mut transition-colors hover:bg-tsm01-acc/15 hover:text-tsm01-ink focus-visible:outline-2 focus-visible:outline-tsm01-acc2 aria-[current=page]:bg-tsm01-acc/20 aria-[current=page]:text-tsm01-ink"><span class="grid size-9 place-items-center rounded-lg bg-white/5 transition-colors group-hover/l:bg-tsm01-acc group-aria-[current=page]/l:bg-tsm01-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="M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/></svg></span>Projects</a></li>
<li class="opacity-0 -translate-x-3 transition-[opacity,translate] duration-300 group-has-checked:translate-x-0 group-has-checked:opacity-100 group-has-checked:delay-[215ms] motion-reduce:transition-none"><a href="#" class="group/l flex min-h-11 items-center gap-3 rounded-xl px-3 text-sm font-medium text-tsm01-mut transition-colors hover:bg-tsm01-acc/15 hover:text-tsm01-ink focus-visible:outline-2 focus-visible:outline-tsm01-acc2 aria-[current=page]:bg-tsm01-acc/20 aria-[current=page]:text-tsm01-ink"><span class="grid size-9 place-items-center rounded-lg bg-white/5 transition-colors group-hover/l:bg-tsm01-acc group-aria-[current=page]/l:bg-tsm01-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="M21 12a8 8 0 0 1-11.6 7.1L4 20l1-4.6A8 8 0 1 1 21 12z"/></svg></span>Messages</a></li>
<li class="opacity-0 -translate-x-3 transition-[opacity,translate] duration-300 group-has-checked:translate-x-0 group-has-checked:opacity-100 group-has-checked:delay-[260ms] motion-reduce:transition-none"><a href="#" class="group/l flex min-h-11 items-center gap-3 rounded-xl px-3 text-sm font-medium text-tsm01-mut transition-colors hover:bg-tsm01-acc/15 hover:text-tsm01-ink focus-visible:outline-2 focus-visible:outline-tsm01-acc2 aria-[current=page]:bg-tsm01-acc/20 aria-[current=page]:text-tsm01-ink"><span class="grid size-9 place-items-center rounded-lg bg-white/5 transition-colors group-hover/l:bg-tsm01-acc group-aria-[current=page]/l:bg-tsm01-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>Settings</a></li>
</ul>
<div class="mx-6 flex items-center gap-3 border-t border-tsm01-acc/20 pt-4">
<span aria-hidden="true" class="grid size-9 place-items-center rounded-full bg-linear-135 from-amber-500 to-red-500 text-[13px] font-bold">JD</span>
<div><p class="text-[13px] font-semibold">Jane Doe</p><p class="text-[11px] text-tsm01-mut">Pro plan</p></div>
</div>
</nav>
<div class="mx-auto w-full max-w-3xl px-6 pt-24 pb-10">
<h1 class="text-[clamp(22px,3vw,28px)] font-bold tracking-tight">Welcome back, Jane</h1>
<p class="mt-2 mb-7 max-w-prose text-sm leading-relaxed text-tsm01-mut text-pretty">Press the menu button to slide the drawer in. Click the dimmed page or press the button again to close it.</p>
<div class="grid grid-cols-2 gap-3 md:grid-cols-4">
<div class="rounded-2xl border border-tsm01-acc/20 bg-tsm01-surface p-4"><p class="text-2xl font-bold tabular-nums text-tsm01-acc2">2,847</p><p class="mt-1 text-xs text-tsm01-mut">Page views</p></div>
<div class="rounded-2xl border border-tsm01-acc/20 bg-tsm01-surface p-4"><p class="text-2xl font-bold tabular-nums text-tsm01-acc2">94%</p><p class="mt-1 text-xs text-tsm01-mut">Uptime</p></div>
<div class="rounded-2xl border border-tsm01-acc/20 bg-tsm01-surface p-4"><p class="text-2xl font-bold tabular-nums text-tsm01-acc2">$12.4k</p><p class="mt-1 text-xs text-tsm01-mut">Revenue</p></div>
<div class="rounded-2xl border border-tsm01-acc/20 bg-tsm01-surface p-4"><p class="text-2xl font-bold tabular-nums text-tsm01-acc2">483</p><p class="mt-1 text-xs text-tsm01-mut">Users</p></div>
</div>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tsm01-bg: #0f172a;
--color-tsm01-bg: oklch(0.208 0.04 265.8);
--color-tsm01-glow: #2a1650;
--color-tsm01-glow: oklch(0.265 0.101 294.4);
--color-tsm01-surface: #1e293b;
--color-tsm01-surface: oklch(0.279 0.037 260);
--color-tsm01-menu: #1a1033;
--color-tsm01-menu: oklch(0.209 0.066 293);
--color-tsm01-acc: #7c3aed;
--color-tsm01-acc: oklch(0.541 0.247 293);
--color-tsm01-acc2: #a78bfa;
--color-tsm01-acc2: oklch(0.709 0.159 293.5);
--color-tsm01-ink: #e2e8f0;
--color-tsm01-ink: oklch(0.929 0.013 255.5);
--color-tsm01-mut: #a3aec2;
--color-tsm01-mut: oklch(0.749 0.031 262.5);
--font-tsm01-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
/* 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-01 {
width: 100%;
min-height: 100svh;
}
```How this works
One checkbox, read from the top. The CSS original depended on input ~ .nav, which forced the input, the burger and the panel to be direct siblings. In v4 the root carries group and every child asks group-has-checked: instead:
<section class="group …">
<input type="checkbox" class="peer sr-only">
<nav class="invisible -translate-x-full
group-has-checked:visible group-has-checked:translate-x-0">The morph is three independent transforms. v4 compiles rotate-45 to the rotate property and translate-y-* to translate, so transition-transform animates both without a combined transform string.
Closed means gone. visibility is transitioned alongside translate, so the panel becomes hidden only after the slide finishes — links are never tabbable while off-screen.
Make it yours
- Speed: change
duration-400on the nav and bars —duration-250is snappier,duration-600more cinematic. - Width: edit
w-[min(280px,86vw)]; themin()keeps the drawer from covering a phone screen edge-to-edge. - Right-hand drawer: swap
left-0 -translate-x-fullforright-0 translate-x-fulland move the burger toright-5. - Re-theme: edit
--color-tsm01-accin@theme— burger hover, active pill, icon tiles and stats all follow.
Gotchas — read before shipping
- Keep the input
sr-only, neverhidden—display:noneremoves it from the keyboard order and the burger can no longer be operated with Space. - The
delay-[…]stagger applies in both directions unless scoped togroup-has-checked:; scoping it there makes closing instant and tidy. group-has-checked:matches any checked descendant — add a second checkbox inside the drawer and name the group (group/menu,group-has-[#id:checked]/menu:).
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
:has() is Chrome 105 / Safari 15.4 / Firefox 121; the floor is Tailwind v4's own sheet (cascade layers, @property, color-mix()).