28 Tailwind Hamburger Menus
13 / 28

All 28 in 28 Tailwind Hamburger Menus

  1. 01Tailwind Hamburger Menu with Clip-Path Circle Expansion
  2. 02Tailwind Keyboard Navigable Hamburger Menu with ARIA Attributes
  3. 03Tailwind Animated 3-Line to X Hamburger Icon Toggle
  4. 04Tailwind Slide-In Off-Canvas Drawer with Dimmed Backdrop Overlay
  5. 05Pure Tailwind Checkbox Hack Hamburger Navigation (No JavaScript)
  6. 06Tailwind Responsive Hamburger Menu with Integrated Search Bar & Social Links
  7. 07Tailwind Glassmorphism Backdrop Blur Hamburger Navigation
  8. 08Tailwind Push Page Navigation Menu (Off-Canvas Content Shift)
  9. 09Pure Tailwind Hamburger Menu Without JavaScript
  10. 10Tailwind Hamburger Menu Morphing to Close Icon Animation
  11. 11Tailwind Full Screen Mobile Navigation Overlay
  12. 12Tailwind Slide Out Sidebar Navigation / Off Canvas Menu
  13. 13Tailwind Responsive Navbar Mobile Hamburger Toggle Breakpoints
  14. 14Tailwind Minimalist Floating Hamburger Button
  15. 15Tailwind CSS Responsive Hamburger Menu Component
  16. 16Tailwind Rebuild of the Bootstrap 5 Navbar Hamburger Toggle
  17. 17Tailwind WCAG Accessible Hamburger Menu Example
  18. 18Pure Tailwind Dropdown Slide Down Mobile Hamburger Menu
  19. 19Simple 3-Line Tailwind Hamburger Icon Hover Effect
  20. 20Tailwind Full Screen Blur Overlay Hamburger Menu
  21. 21Tailwind Mobile Bottom Navigation Bar with Floating Hamburger Toggle
  22. 22Pure Tailwind Multi-Level Accordion Hamburger Dropdown Menu
  23. 23Flexbox Navbar Right-Aligned Tailwind Hamburger Icon
  24. 24Radial Ripple Expand Tailwind Hamburger Menu
  25. 25Sticky Tailwind Navbar Shrinking Hamburger Icon on Scroll
  26. 26Neumorphic Tailwind Hamburger Toggle Button
  27. 27Brutalist Design Bordered Tailwind Hamburger Menu
  28. 28Tailwind 3D Flip Canvas Mobile Hamburger Navigation
Pure TailwindMIT licensed

Tailwind Responsive Navbar Mobile Hamburger Toggle Breakpoints

The breakpoint swap every site ships — inline links wide, hamburger narrow — and Tailwind v4's container-query variants make it read like a sentence: @max-lg:hidden on the desktop row, @max-lg:grid on the burger. Drag the stage's right edge and watch the swap happen live. Zero JavaScript, because the toggle is a peer checkbox.

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="thb-13 w-full min-h-svh bg-thb13-bg font-thb13-sans text-thb13-ink px-5 py-9" aria-label="Responsive navbar breakpoint demo">
  <div class="p-5 rounded-[18px] border border-thb13-edge bg-thb13-bg">
    <p class="mb-3.5 font-thb13-mono text-xs text-thb13-mut" aria-hidden="true">&harr; drag the right edge &mdash; the navbar watches its own width</p>
    <div class="resize-x overflow-hidden w-full max-w-full min-w-[min(300px,100%)] pr-3.5 border-r-[3px] border-dashed border-[color-mix(in_oklch,var(--color-thb13-acc)_45%,var(--color-thb13-edge))]">
      <div class="@container">
        <header class="group relative flex flex-wrap items-center gap-6.5 min-h-16 px-5 py-2 rounded-[14px] border border-thb13-edge bg-thb13-panel shadow-[0_12px_30px_-22px_oklch(0.35_0.05_265/0.5)]">
          <input type="checkbox" id="thb13-t" class="peer absolute w-px h-px overflow-hidden whitespace-nowrap [clip-path:inset(50%)]">
          <span class="flex items-center gap-2.25 text-[15px] font-extrabold tracking-[-0.01em]">
            <i class="w-4.75 h-4.75 rounded-md rotate-8 bg-[conic-gradient(from_210deg,var(--color-thb13-acc),oklch(0.72_0.13_200))]" aria-hidden="true"></i>Statement
          </span>
          <nav aria-label="Primary" class="flex gap-1 ml-1.5 @max-lg:hidden">
            <a href="#product" aria-current="page" class="group relative px-3 py-2.25 rounded-md text-[13.5px] font-semibold text-thb13-mut no-underline transition-[color] duration-200 hover:text-thb13-ink focus-visible:text-thb13-ink focus-visible:outline-2 focus-visible:outline-thb13-acc focus-visible:outline-offset-2 aria-current:text-thb13-ink">Product<span class="absolute inset-x-3 bottom-1 h-0.5 rounded-sm bg-thb13-acc scale-x-0 origin-left transition-[scale] duration-250 ease-thb13 group-hover:scale-x-100 group-focus-visible:scale-x-100 group-aria-current:scale-x-100" aria-hidden="true"></span></a>
            <a href="#method" class="group relative px-3 py-2.25 rounded-md text-[13.5px] font-semibold text-thb13-mut no-underline transition-[color] duration-200 hover:text-thb13-ink focus-visible:text-thb13-ink focus-visible:outline-2 focus-visible:outline-thb13-acc focus-visible:outline-offset-2">Method<span class="absolute inset-x-3 bottom-1 h-0.5 rounded-sm bg-thb13-acc scale-x-0 origin-left transition-[scale] duration-250 ease-thb13 group-hover:scale-x-100 group-focus-visible:scale-x-100" aria-hidden="true"></span></a>
            <a href="#pricing" class="group relative px-3 py-2.25 rounded-md text-[13.5px] font-semibold text-thb13-mut no-underline transition-[color] duration-200 hover:text-thb13-ink focus-visible:text-thb13-ink focus-visible:outline-2 focus-visible:outline-thb13-acc focus-visible:outline-offset-2">Pricing<span class="absolute inset-x-3 bottom-1 h-0.5 rounded-sm bg-thb13-acc scale-x-0 origin-left transition-[scale] duration-250 ease-thb13 group-hover:scale-x-100 group-focus-visible:scale-x-100" aria-hidden="true"></span></a>
            <a href="#company" class="group relative px-3 py-2.25 rounded-md text-[13.5px] font-semibold text-thb13-mut no-underline transition-[color] duration-200 hover:text-thb13-ink focus-visible:text-thb13-ink focus-visible:outline-2 focus-visible:outline-thb13-acc focus-visible:outline-offset-2">Company<span class="absolute inset-x-3 bottom-1 h-0.5 rounded-sm bg-thb13-acc scale-x-0 origin-left transition-[scale] duration-250 ease-thb13 group-hover:scale-x-100 group-focus-visible:scale-x-100" aria-hidden="true"></span></a>
          </nav>
          <a href="#start" class="inline-flex items-center ml-auto min-h-10 px-4.5 rounded-[10px] bg-thb13-ink text-thb13-bg text-[13px] font-bold no-underline transition-[background,translate] duration-200 hover:bg-thb13-acc active:translate-y-px focus-visible:outline-2 focus-visible:outline-thb13-acc focus-visible:outline-offset-2">Get started</a>
          <label for="thb13-t" class="hidden order-5 w-11 h-11 place-items-center rounded-[11px] border border-thb13-edge cursor-pointer select-none transition-[background] duration-200 hover:bg-thb13-hover peer-focus-visible:outline-2 peer-focus-visible:outline-thb13-acc peer-focus-visible:outline-offset-2 @max-lg:grid" aria-hidden="true">
            <span class="relative block w-4.5 h-3">
              <i class="absolute left-0 top-0 w-4.5 h-0.5 rounded-sm bg-thb13-ink transition-[translate,rotate] duration-280 group-has-checked:translate-y-[5px] group-has-checked:rotate-45 motion-reduce:transition-none"></i>
              <i class="absolute left-0 top-[5px] w-4.5 h-0.5 rounded-sm bg-thb13-ink transition-[opacity] duration-200 group-has-checked:opacity-0 motion-reduce:transition-none"></i>
              <i class="absolute left-0 top-2.5 w-4.5 h-0.5 rounded-sm bg-thb13-ink transition-[translate,rotate] duration-280 group-has-checked:-translate-y-[5px] group-has-checked:-rotate-45 motion-reduce:transition-none"></i>
            </span>
          </label>
          <nav aria-label="Primary mobile" class="hidden basis-full min-w-0 opacity-0 [grid-template-rows:0fr] transition-[grid-template-rows,opacity] duration-350 ease-thb13 group-has-checked:opacity-100 group-has-checked:[grid-template-rows:1fr] @max-lg:grid @min-lg:hidden motion-reduce:transition-none">
            <ul class="list-none grid min-h-0 overflow-hidden pt-1.5 group-has-checked:mt-1 group-has-checked:border-t group-has-checked:border-thb13-edge">
              <li><a href="#product" aria-current="page" class="flex items-center min-h-11.5 px-3 rounded-[9px] text-sm font-semibold text-thb13-mut no-underline transition-[background,color] duration-150 hover:bg-thb13-hover hover:text-thb13-ink focus-visible:outline-2 focus-visible:outline-thb13-acc focus-visible:-outline-offset-2 aria-current:text-thb13-acc">Product</a></li>
              <li><a href="#method" class="flex items-center min-h-11.5 px-3 rounded-[9px] text-sm font-semibold text-thb13-mut no-underline transition-[background,color] duration-150 hover:bg-thb13-hover hover:text-thb13-ink focus-visible:outline-2 focus-visible:outline-thb13-acc focus-visible:-outline-offset-2">Method</a></li>
              <li><a href="#pricing" class="flex items-center min-h-11.5 px-3 rounded-[9px] text-sm font-semibold text-thb13-mut no-underline transition-[background,color] duration-150 hover:bg-thb13-hover hover:text-thb13-ink focus-visible:outline-2 focus-visible:outline-thb13-acc focus-visible:-outline-offset-2">Pricing</a></li>
              <li><a href="#company" class="flex items-center min-h-11.5 px-3 rounded-[9px] text-sm font-semibold text-thb13-mut no-underline transition-[background,color] duration-150 hover:bg-thb13-hover hover:text-thb13-ink focus-visible:outline-2 focus-visible:outline-thb13-acc focus-visible:-outline-offset-2">Company</a></li>
            </ul>
          </nav>
        </header>
        <div class="grid gap-3 px-1 py-4.5" aria-hidden="true">
          <div class="h-2.75 w-[64%] rounded-full bg-thb13-line"></div>
          <div class="h-2.75 w-[82%] rounded-full bg-thb13-line"></div>
          <div class="h-2.75 w-[47%] rounded-full bg-thb13-line"></div>
        </div>
      </div>
    </div>
  </div>
</section>
@import "tailwindcss";

@theme {
  --color-thb13-bg: #fafafc;
  --color-thb13-bg: oklch(0.975 0.004 260);
  --color-thb13-panel: #ffffff;
  --color-thb13-panel: oklch(1 0 0);
  --color-thb13-hover: #f2f2f7;
  --color-thb13-hover: oklch(0.96 0.008 260);
  --color-thb13-edge: #e2e2e9;
  --color-thb13-edge: oklch(0.89 0.009 260);
  --color-thb13-line: #e6e6ed;
  --color-thb13-line: oklch(0.9 0.007 260);
  --color-thb13-ink: #32334a;
  --color-thb13-ink: oklch(0.24 0.018 262);
  --color-thb13-mut: #71738c;
  --color-thb13-mut: oklch(0.53 0.015 262);
  --color-thb13-acc: #5340e0;
  --color-thb13-acc: oklch(0.58 0.2 275);
  --font-thb13-sans: 'Space Grotesk', system-ui, sans-serif;
  --font-thb13-mono: 'JetBrains Mono', ui-monospace, monospace;
  --ease-thb13: cubic-bezier(0.2, 0.7, 0.2, 1);
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's
   w-full min-h-svh. It scopes the demo, and it holds the stage at full height in the
   moment before the browser build has compiled its utilities. */

.thb-13 {
  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-thb13-bg: #fafafc;
  --color-thb13-bg: oklch(0.975 0.004 260);
  --color-thb13-panel: #ffffff;
  --color-thb13-panel: oklch(1 0 0);
  --color-thb13-hover: #f2f2f7;
  --color-thb13-hover: oklch(0.96 0.008 260);
  --color-thb13-edge: #e2e2e9;
  --color-thb13-edge: oklch(0.89 0.009 260);
  --color-thb13-line: #e6e6ed;
  --color-thb13-line: oklch(0.9 0.007 260);
  --color-thb13-ink: #32334a;
  --color-thb13-ink: oklch(0.24 0.018 262);
  --color-thb13-mut: #71738c;
  --color-thb13-mut: oklch(0.53 0.015 262);
  --color-thb13-acc: #5340e0;
  --color-thb13-acc: oklch(0.58 0.2 275);
  --font-thb13-sans: 'Space Grotesk', system-ui, sans-serif;
  --font-thb13-mono: 'JetBrains Mono', ui-monospace, monospace;
  --ease-thb13: cubic-bezier(0.2, 0.7, 0.2, 1);
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's
   w-full min-h-svh. It scopes the demo, and it holds the stage at full height in the
   moment before the browser build has compiled its utilities. */

.thb-13 {
  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=Space+Grotesk:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;600&display=swap">

What changed in the port

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

  • The @container (max-width:620px) block disappears entirely. Its five contained rules become @max-lg: variants on the five elements they applied to, so each element states its own narrow-state behaviour.
  • container-type:inline-size becomes the @container utility on the wrapper — one word instead of a rule, and impossible to put on the wrong element without noticing.
  • The resize bug fix is now visible in the markup: the panel carries @max-lg:grid @min-lg:hidden side by side, where the CSS version relies on a display:none default that lives far from the at-rule.
  • The ::after underline becomes an aria-hidden span so it can read group-hover:, group-focus-visible: and group-aria-current: — the three states are typed together and cannot drift apart.
  • Variant names are theme breakpoints, not raw pixels. @max-lg replaces the hand-picked 620px; @max-[620px] is available when the exact number matters.
  • Still zero JavaScript: peer + peer-checked: carries the toggle, with the same trade-offs demo 05 documents.
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 Responsive Navbar Mobile Hamburger Toggle Breakpoints
Source: https://codefronts.com/navigation/tailwind-hamburger-menus/tailwind-responsive-navbar-mobile-hamburger-toggle-breakpoints/

The breakpoint swap every site ships &mdash; inline links wide, hamburger narrow &mdash; and Tailwind v4's container-query variants make it read like a sentence: @max-lg:hidden on the desktop row, @max-lg:grid on the burger. Drag the stage's right edge and watch the swap happen live. Zero JavaScript, because the toggle is a peer checkbox.
## HTML
```html
<section class="thb-13 w-full min-h-svh bg-thb13-bg font-thb13-sans text-thb13-ink px-5 py-9" aria-label="Responsive navbar breakpoint demo">
  <div class="p-5 rounded-[18px] border border-thb13-edge bg-thb13-bg">
    <p class="mb-3.5 font-thb13-mono text-xs text-thb13-mut" aria-hidden="true">&harr; drag the right edge &mdash; the navbar watches its own width</p>
    <div class="resize-x overflow-hidden w-full max-w-full min-w-[min(300px,100%)] pr-3.5 border-r-[3px] border-dashed border-[color-mix(in_oklch,var(--color-thb13-acc)_45%,var(--color-thb13-edge))]">
      <div class="@container">
        <header class="group relative flex flex-wrap items-center gap-6.5 min-h-16 px-5 py-2 rounded-[14px] border border-thb13-edge bg-thb13-panel shadow-[0_12px_30px_-22px_oklch(0.35_0.05_265/0.5)]">
          <input type="checkbox" id="thb13-t" class="peer absolute w-px h-px overflow-hidden whitespace-nowrap [clip-path:inset(50%)]">
          <span class="flex items-center gap-2.25 text-[15px] font-extrabold tracking-[-0.01em]">
            <i class="w-4.75 h-4.75 rounded-md rotate-8 bg-[conic-gradient(from_210deg,var(--color-thb13-acc),oklch(0.72_0.13_200))]" aria-hidden="true"></i>Statement
          </span>
          <nav aria-label="Primary" class="flex gap-1 ml-1.5 @max-lg:hidden">
            <a href="#product" aria-current="page" class="group relative px-3 py-2.25 rounded-md text-[13.5px] font-semibold text-thb13-mut no-underline transition-[color] duration-200 hover:text-thb13-ink focus-visible:text-thb13-ink focus-visible:outline-2 focus-visible:outline-thb13-acc focus-visible:outline-offset-2 aria-current:text-thb13-ink">Product<span class="absolute inset-x-3 bottom-1 h-0.5 rounded-sm bg-thb13-acc scale-x-0 origin-left transition-[scale] duration-250 ease-thb13 group-hover:scale-x-100 group-focus-visible:scale-x-100 group-aria-current:scale-x-100" aria-hidden="true"></span></a>
            <a href="#method" class="group relative px-3 py-2.25 rounded-md text-[13.5px] font-semibold text-thb13-mut no-underline transition-[color] duration-200 hover:text-thb13-ink focus-visible:text-thb13-ink focus-visible:outline-2 focus-visible:outline-thb13-acc focus-visible:outline-offset-2">Method<span class="absolute inset-x-3 bottom-1 h-0.5 rounded-sm bg-thb13-acc scale-x-0 origin-left transition-[scale] duration-250 ease-thb13 group-hover:scale-x-100 group-focus-visible:scale-x-100" aria-hidden="true"></span></a>
            <a href="#pricing" class="group relative px-3 py-2.25 rounded-md text-[13.5px] font-semibold text-thb13-mut no-underline transition-[color] duration-200 hover:text-thb13-ink focus-visible:text-thb13-ink focus-visible:outline-2 focus-visible:outline-thb13-acc focus-visible:outline-offset-2">Pricing<span class="absolute inset-x-3 bottom-1 h-0.5 rounded-sm bg-thb13-acc scale-x-0 origin-left transition-[scale] duration-250 ease-thb13 group-hover:scale-x-100 group-focus-visible:scale-x-100" aria-hidden="true"></span></a>
            <a href="#company" class="group relative px-3 py-2.25 rounded-md text-[13.5px] font-semibold text-thb13-mut no-underline transition-[color] duration-200 hover:text-thb13-ink focus-visible:text-thb13-ink focus-visible:outline-2 focus-visible:outline-thb13-acc focus-visible:outline-offset-2">Company<span class="absolute inset-x-3 bottom-1 h-0.5 rounded-sm bg-thb13-acc scale-x-0 origin-left transition-[scale] duration-250 ease-thb13 group-hover:scale-x-100 group-focus-visible:scale-x-100" aria-hidden="true"></span></a>
          </nav>
          <a href="#start" class="inline-flex items-center ml-auto min-h-10 px-4.5 rounded-[10px] bg-thb13-ink text-thb13-bg text-[13px] font-bold no-underline transition-[background,translate] duration-200 hover:bg-thb13-acc active:translate-y-px focus-visible:outline-2 focus-visible:outline-thb13-acc focus-visible:outline-offset-2">Get started</a>
          <label for="thb13-t" class="hidden order-5 w-11 h-11 place-items-center rounded-[11px] border border-thb13-edge cursor-pointer select-none transition-[background] duration-200 hover:bg-thb13-hover peer-focus-visible:outline-2 peer-focus-visible:outline-thb13-acc peer-focus-visible:outline-offset-2 @max-lg:grid" aria-hidden="true">
            <span class="relative block w-4.5 h-3">
              <i class="absolute left-0 top-0 w-4.5 h-0.5 rounded-sm bg-thb13-ink transition-[translate,rotate] duration-280 group-has-checked:translate-y-[5px] group-has-checked:rotate-45 motion-reduce:transition-none"></i>
              <i class="absolute left-0 top-[5px] w-4.5 h-0.5 rounded-sm bg-thb13-ink transition-[opacity] duration-200 group-has-checked:opacity-0 motion-reduce:transition-none"></i>
              <i class="absolute left-0 top-2.5 w-4.5 h-0.5 rounded-sm bg-thb13-ink transition-[translate,rotate] duration-280 group-has-checked:-translate-y-[5px] group-has-checked:-rotate-45 motion-reduce:transition-none"></i>
            </span>
          </label>
          <nav aria-label="Primary mobile" class="hidden basis-full min-w-0 opacity-0 [grid-template-rows:0fr] transition-[grid-template-rows,opacity] duration-350 ease-thb13 group-has-checked:opacity-100 group-has-checked:[grid-template-rows:1fr] @max-lg:grid @min-lg:hidden motion-reduce:transition-none">
            <ul class="list-none grid min-h-0 overflow-hidden pt-1.5 group-has-checked:mt-1 group-has-checked:border-t group-has-checked:border-thb13-edge">
              <li><a href="#product" aria-current="page" class="flex items-center min-h-11.5 px-3 rounded-[9px] text-sm font-semibold text-thb13-mut no-underline transition-[background,color] duration-150 hover:bg-thb13-hover hover:text-thb13-ink focus-visible:outline-2 focus-visible:outline-thb13-acc focus-visible:-outline-offset-2 aria-current:text-thb13-acc">Product</a></li>
              <li><a href="#method" class="flex items-center min-h-11.5 px-3 rounded-[9px] text-sm font-semibold text-thb13-mut no-underline transition-[background,color] duration-150 hover:bg-thb13-hover hover:text-thb13-ink focus-visible:outline-2 focus-visible:outline-thb13-acc focus-visible:-outline-offset-2">Method</a></li>
              <li><a href="#pricing" class="flex items-center min-h-11.5 px-3 rounded-[9px] text-sm font-semibold text-thb13-mut no-underline transition-[background,color] duration-150 hover:bg-thb13-hover hover:text-thb13-ink focus-visible:outline-2 focus-visible:outline-thb13-acc focus-visible:-outline-offset-2">Pricing</a></li>
              <li><a href="#company" class="flex items-center min-h-11.5 px-3 rounded-[9px] text-sm font-semibold text-thb13-mut no-underline transition-[background,color] duration-150 hover:bg-thb13-hover hover:text-thb13-ink focus-visible:outline-2 focus-visible:outline-thb13-acc focus-visible:-outline-offset-2">Company</a></li>
            </ul>
          </nav>
        </header>
        <div class="grid gap-3 px-1 py-4.5" aria-hidden="true">
          <div class="h-2.75 w-[64%] rounded-full bg-thb13-line"></div>
          <div class="h-2.75 w-[82%] rounded-full bg-thb13-line"></div>
          <div class="h-2.75 w-[47%] rounded-full bg-thb13-line"></div>
        </div>
      </div>
    </div>
  </div>
</section>
```
## CSS
```css
@import "tailwindcss";

@theme {
  --color-thb13-bg: #fafafc;
  --color-thb13-bg: oklch(0.975 0.004 260);
  --color-thb13-panel: #ffffff;
  --color-thb13-panel: oklch(1 0 0);
  --color-thb13-hover: #f2f2f7;
  --color-thb13-hover: oklch(0.96 0.008 260);
  --color-thb13-edge: #e2e2e9;
  --color-thb13-edge: oklch(0.89 0.009 260);
  --color-thb13-line: #e6e6ed;
  --color-thb13-line: oklch(0.9 0.007 260);
  --color-thb13-ink: #32334a;
  --color-thb13-ink: oklch(0.24 0.018 262);
  --color-thb13-mut: #71738c;
  --color-thb13-mut: oklch(0.53 0.015 262);
  --color-thb13-acc: #5340e0;
  --color-thb13-acc: oklch(0.58 0.2 275);
  --font-thb13-sans: 'Space Grotesk', system-ui, sans-serif;
  --font-thb13-mono: 'JetBrains Mono', ui-monospace, monospace;
  --ease-thb13: cubic-bezier(0.2, 0.7, 0.2, 1);
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's
   w-full min-h-svh. It scopes the demo, and it holds the stage at full height in the
   moment before the browser build has compiled its utilities. */

.thb-13 {
  width: 100%;
  min-height: 100svh;
}
```

How this works

One breakpoint, two mutually exclusive displays — expressed on the elements.

<div class="@container">
  <nav class="flex … ">
    <div class="flex @max-lg:hidden">…desktop links…</div>
    <label class="hidden @max-lg:grid">burger</label>
    <nav class="hidden @max-lg:grid @min-lg:hidden">…panel…</nav>
  </nav>
</div>

The media-query translation is mechanical: drop @container and swap @max-lg: for max-lg:. Prefer the container version anywhere the navbar might be embedded — docs sites, admin shells, Storybook. A navbar that is 700px wide inside a split page IS mobile, whatever the viewport says.

The resize bug, fixed by a utility. The panel is @max-lg:grid @min-lg:hidden: open it narrow, widen the stage, and it disappears rather than hanging under a row of visible links. State and presentation stay cleanly separated — the checkbox is still checked, it just has no visual consequence at that size.

The underline is a span, not a pseudo-element. scale-x-0 origin-left growing under group-hover:, group-focus-visible: and aria-current: — three states, one element, and hover and focus are guaranteed to match because they are typed next to each other.

Drag affordance is stock CSS. resize-x overflow-hidden. Ship that pair on any demo you publish: readers who understand responsiveness by dragging beat any animated GIF.

Make it yours

  • The breakpoint appears in the variant name. Swap every @max-lg:/@min-lg: pair for @max-xl:/@min-xl: to hold the burger until wider — measure where your real nav crowds, do not guess.
  • Add a link and it joins both states: the desktop row and the mobile panel are separate lists here, so keep them in sync (or render both from one array).
  • The CTA stays visible in both states, which is the common choice for &ldquo;Get started&rdquo;. Move it inside the panel to collapse it too.
  • Swap the checkbox for demo 02's button + JS when this graduates from marketing page to app; the visual states do not change.
  • Retheme through --color-thb13-acc — underline, CTA hover and focus rings all read it.

Gotchas — read before shipping

  • @container goes on the WRAPPER. A container cannot restyle itself, only its descendants — put it on the navbar and the variants silently never match.
  • Hide the desktop row with hidden (display), never invisible or opacity-0: hidden-but-present links stay keyboard-focusable in mobile state.
  • The classic burger bug is forgetting to hide the PANEL in the wide state. Without @min-lg:hidden it hangs under the desktop row after a resize.
  • peer-checked: requires the checkbox to be a preceding sibling of the panel. Tailwind does not lift the DOM constraint — demo 09 does, with has-checked:.
  • The container-query variant names are relative to your theme's breakpoints; @max-lg is not the same number as a raw 620px, so if you need that exact value use @max-[620px]:.
  • resize-x needs a non-visible overflow to work, and it only draws a corner grabber — the dashed edge in this demo is a hint, not the handle.

Browser support

ChromeSafariFirefoxEdge
111+16.4+128+111+

Size container queries are Chrome 105, Safari 16 and Firefox 110 — Baseline 2023. The media-query variant runs in anything from the last decade. resize is desktop sugar; touch users get a static (still responsive) stage.

Techniques used in this demo

Search CodeFronts

Loading…