06 / 28
All 28 in 28 Tailwind Hamburger Menus
- 01Tailwind Hamburger Menu with Clip-Path Circle Expansion
- 02Tailwind Keyboard Navigable Hamburger Menu with ARIA Attributes
- 03Tailwind Animated 3-Line to X Hamburger Icon Toggle
- 04Tailwind Slide-In Off-Canvas Drawer with Dimmed Backdrop Overlay
- 05Pure Tailwind Checkbox Hack Hamburger Navigation (No JavaScript)
- 06Tailwind Responsive Hamburger Menu with Integrated Search Bar & Social Links
- 07Tailwind Glassmorphism Backdrop Blur Hamburger Navigation
- 08Tailwind Push Page Navigation Menu (Off-Canvas Content Shift)
- 09Pure Tailwind Hamburger Menu Without JavaScript
- 10Tailwind Hamburger Menu Morphing to Close Icon Animation
- 11Tailwind Full Screen Mobile Navigation Overlay
- 12Tailwind Slide Out Sidebar Navigation / Off Canvas Menu
- 13Tailwind Responsive Navbar Mobile Hamburger Toggle Breakpoints
- 14Tailwind Minimalist Floating Hamburger Button
- 15Tailwind CSS Responsive Hamburger Menu Component
- 16Tailwind Rebuild of the Bootstrap 5 Navbar Hamburger Toggle
- 17Tailwind WCAG Accessible Hamburger Menu Example
- 18Pure Tailwind Dropdown Slide Down Mobile Hamburger Menu
- 19Simple 3-Line Tailwind Hamburger Icon Hover Effect
- 20Tailwind Full Screen Blur Overlay Hamburger Menu
- 21Tailwind Mobile Bottom Navigation Bar with Floating Hamburger Toggle
- 22Pure Tailwind Multi-Level Accordion Hamburger Dropdown Menu
- 23Flexbox Navbar Right-Aligned Tailwind Hamburger Icon
- 24Radial Ripple Expand Tailwind Hamburger Menu
- 25Sticky Tailwind Navbar Shrinking Hamburger Icon on Scroll
- 26Neumorphic Tailwind Hamburger Toggle Button
- 27Brutalist Design Bordered Tailwind Hamburger Menu
- 28Tailwind 3D Flip Canvas Mobile Hamburger Navigation
Tailwind Responsive Hamburger Menu with Integrated Search Bar & Social Links
The publisher/e-commerce drawer that carries a whole header's worth of jobs — auto-focused search, nav with counts, a New badge, a social row and a pinned newsletter CTA. The port's real content is one class list: grid grid-rows-[auto_1fr_auto] on the drawer plus min-h-0 overflow-auto on the middle row, which is the whole reason feature-rich drawers stop losing their footer.
Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time
Untitled UI React · Affiliate link
The code
<section class="thb-06 w-full min-h-svh grid justify-center content-start bg-thb06-bg font-thb06-sans text-thb06-ink px-5 py-9" aria-label="Hamburger menu with search and social links demo">
<div class="group relative w-[min(400px,88vw)] h-140 rounded-3xl overflow-hidden bg-thb06-bg border border-thb06-edge">
<header class="flex items-center gap-3 h-16.5 px-4.5 bg-thb06-panel border-b border-thb06-edge">
<button type="button" aria-expanded="false" aria-controls="thb06-drawer" aria-label="Open menu" class="grid place-items-center w-11 h-11 -ml-2 rounded-xl border-0 bg-transparent text-thb06-ink cursor-pointer transition-[background] duration-200 hover:bg-thb06-hover focus-visible:outline-2 focus-visible:outline-thb06-acc focus-visible:outline-offset-2">
<span class="relative block w-5 h-3.5" aria-hidden="true">
<i class="absolute left-0 top-0 w-5 h-0.5 rounded-sm bg-current"></i>
<i class="absolute left-0 top-1.5 w-5 h-0.5 rounded-sm bg-current"></i>
<i class="absolute left-0 top-3 w-5 h-0.5 rounded-sm bg-current"></i>
</span>
</button>
<span class="text-[17px] font-extrabold tracking-[0.14em]">KIOSK<i class="not-italic font-normal tracking-normal text-thb06-acc">daily</i></span>
<span class="relative ml-auto text-thb06-ink" aria-hidden="true">
<svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"><path d="M4.5 7h15L18 20H6Z"/><path d="M8.5 7a3.5 3.5 0 0 1 7 0"/></svg>
<b class="absolute -top-1.75 -right-2.25 px-1.5 py-px rounded-full bg-thb06-acc text-white text-[9.5px] font-bold">2</b>
</span>
</header>
<div class="grid gap-3.25 p-4.5" aria-hidden="true">
<div class="h-45 rounded-[14px] bg-linear-[145deg,oklch(0.9_0.03_50),oklch(0.85_0.055_25)]"></div>
<div class="h-2.75 w-[86%] rounded-full bg-thb06-line"></div>
<div class="h-2.75 w-[64%] rounded-full bg-thb06-line"></div>
</div>
<button type="button" tabindex="-1" aria-hidden="true" class="absolute inset-0 z-2 border-0 p-0 cursor-pointer opacity-0 invisible bg-[oklch(0.22_0.02_40/0.42)] backdrop-blur-[2px] [transition:opacity_.3s,visibility_0s_.3s] group-data-open:opacity-100 group-data-open:visible group-data-open:[transition:opacity_.3s,visibility_0s_0s]"></button>
<aside id="thb06-drawer" aria-label="Menu" class="absolute inset-y-0 left-0 z-3 grid grid-rows-[auto_1fr_auto] w-[min(88%,330px)] bg-thb06-panel shadow-[24px_0_48px_-24px_oklch(0.25_0.03_40/0.45)] -translate-x-[102%] invisible [transition:translate_.42s_var(--ease-thb06),visibility_0s_.42s] group-data-open:translate-x-0 group-data-open:visible group-data-open:[transition:translate_.42s_var(--ease-thb06),visibility_0s_0s] motion-reduce:[transition:opacity_.15s,visibility_0s_.15s]">
<div class="flex items-center gap-2.5 px-4 pt-4 pb-3">
<form role="search" class="flex flex-1 items-center gap-2.25 min-h-11 px-3.5 rounded-xl border-[1.5px] border-thb06-edge text-thb06-mut transition-[border-color,color] duration-200 focus-within:border-thb06-acc focus-within:text-thb06-acc">
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><circle cx="11" cy="11" r="7"/><path d="m20 20-3.5-3.5"/></svg>
<input type="search" placeholder="Search stories, topics…" aria-label="Search" class="flex-1 min-w-0 border-0 outline-none bg-transparent font-thb06-sans text-sm text-thb06-ink">
</form>
<button type="button" aria-label="Close menu" class="grid place-items-center shrink-0 w-11 h-11 rounded-xl border-[1.5px] border-thb06-edge bg-thb06-panel text-thb06-ink cursor-pointer transition-[background] duration-200 hover:bg-thb06-hover focus-visible:outline-2 focus-visible:outline-thb06-acc focus-visible:outline-offset-2">
<svg viewBox="0 0 24 24" width="15" height="15" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" aria-hidden="true"><path d="m6 6 12 12M18 6 6 18"/></svg>
</button>
</div>
<nav aria-label="Sections" class="flex flex-col min-h-0 overflow-auto overscroll-contain px-2.5 py-1">
<a href="#latest" class="flex items-center justify-between gap-3 min-h-12.5 px-3 rounded-[11px] no-underline text-[15.5px] font-bold tracking-[-0.01em] text-thb06-ink transition-[background,color] duration-150 hover:bg-thb06-hover hover:text-thb06-acc focus-visible:outline-2 focus-visible:outline-thb06-acc focus-visible:-outline-offset-2">Latest<span class="text-[11.5px] font-semibold text-thb06-mut tabular-nums">128</span></a>
<a href="#tech" class="flex items-center justify-between gap-3 min-h-12.5 px-3 rounded-[11px] no-underline text-[15.5px] font-bold tracking-[-0.01em] text-thb06-ink transition-[background,color] duration-150 hover:bg-thb06-hover hover:text-thb06-acc focus-visible:outline-2 focus-visible:outline-thb06-acc focus-visible:-outline-offset-2">Technology<span class="text-[11.5px] font-semibold text-thb06-mut tabular-nums">41</span></a>
<a href="#design" class="flex items-center justify-between gap-3 min-h-12.5 px-3 rounded-[11px] no-underline text-[15.5px] font-bold tracking-[-0.01em] text-thb06-ink transition-[background,color] duration-150 hover:bg-thb06-hover hover:text-thb06-acc focus-visible:outline-2 focus-visible:outline-thb06-acc focus-visible:-outline-offset-2">Design<span class="text-[11.5px] font-semibold text-thb06-mut tabular-nums">27</span></a>
<a href="#culture" class="flex items-center justify-between gap-3 min-h-12.5 px-3 rounded-[11px] no-underline text-[15.5px] font-bold tracking-[-0.01em] text-thb06-ink transition-[background,color] duration-150 hover:bg-thb06-hover hover:text-thb06-acc focus-visible:outline-2 focus-visible:outline-thb06-acc focus-visible:-outline-offset-2">Culture<b class="px-2 py-0.75 rounded-full bg-thb06-acc text-white text-[10px] font-extrabold tracking-[0.08em] uppercase">New</b></a>
<a href="#podcasts" class="flex items-center justify-between gap-3 min-h-12.5 px-3 rounded-[11px] no-underline text-[15.5px] font-bold tracking-[-0.01em] text-thb06-ink transition-[background,color] duration-150 hover:bg-thb06-hover hover:text-thb06-acc focus-visible:outline-2 focus-visible:outline-thb06-acc focus-visible:-outline-offset-2">Podcasts<span class="text-[11.5px] font-semibold text-thb06-mut tabular-nums">12</span></a>
<a href="#archive" class="flex items-center justify-between gap-3 min-h-12.5 px-3 rounded-[11px] no-underline text-[15.5px] font-bold tracking-[-0.01em] text-thb06-ink transition-[background,color] duration-150 hover:bg-thb06-hover hover:text-thb06-acc focus-visible:outline-2 focus-visible:outline-thb06-acc focus-visible:-outline-offset-2">Archive</a>
</nav>
<footer class="grid gap-3 px-4 pt-3.5 pb-4.5 border-t border-thb06-edge">
<div class="flex gap-2">
<a href="#x" aria-label="Follow on X" class="grid place-items-center w-11 h-11 rounded-xl border-[1.5px] border-thb06-edge text-thb06-ink transition-[border-color,color,translate] duration-200 hover:border-thb06-acc hover:text-thb06-acc hover:-translate-y-0.5 focus-visible:border-thb06-acc focus-visible:text-thb06-acc focus-visible:outline-2 focus-visible:outline-thb06-acc focus-visible:outline-offset-2"><svg viewBox="0 0 24 24" class="w-4.5 h-4.5 fill-current" aria-hidden="true"><path d="M4 4l7.2 9.3L4.4 20h2.1l5.6-5.5L16.8 20H20l-7.5-9.7L18.9 4h-2.1l-5.2 5.1L7.2 4H4Z"/></svg></a>
<a href="#instagram" aria-label="Follow on Instagram" class="grid place-items-center w-11 h-11 rounded-xl border-[1.5px] border-thb06-edge text-thb06-ink transition-[border-color,color,translate] duration-200 hover:border-thb06-acc hover:text-thb06-acc hover:-translate-y-0.5 focus-visible:border-thb06-acc focus-visible:text-thb06-acc focus-visible:outline-2 focus-visible:outline-thb06-acc focus-visible:outline-offset-2"><svg viewBox="0 0 24 24" class="w-4.5 h-4.5 fill-current" aria-hidden="true"><rect x="3.5" y="3.5" width="17" height="17" rx="4.5" fill="none" stroke="currentColor" stroke-width="1.8"/><circle cx="12" cy="12" r="4" fill="none" stroke="currentColor" stroke-width="1.8"/><circle cx="17.2" cy="6.8" r="1.3"/></svg></a>
<a href="#youtube" aria-label="Subscribe on YouTube" class="grid place-items-center w-11 h-11 rounded-xl border-[1.5px] border-thb06-edge text-thb06-ink transition-[border-color,color,translate] duration-200 hover:border-thb06-acc hover:text-thb06-acc hover:-translate-y-0.5 focus-visible:border-thb06-acc focus-visible:text-thb06-acc focus-visible:outline-2 focus-visible:outline-thb06-acc focus-visible:outline-offset-2"><svg viewBox="0 0 24 24" class="w-4.5 h-4.5 fill-current" aria-hidden="true"><rect x="2.5" y="6" width="19" height="12" rx="3.5" fill="none" stroke="currentColor" stroke-width="1.8"/><path d="M10.5 9.8v4.4l4-2.2Z"/></svg></a>
<a href="#rss" aria-label="RSS feed" class="grid place-items-center w-11 h-11 rounded-xl border-[1.5px] border-thb06-edge text-thb06-ink transition-[border-color,color,translate] duration-200 hover:border-thb06-acc hover:text-thb06-acc hover:-translate-y-0.5 focus-visible:border-thb06-acc focus-visible:text-thb06-acc focus-visible:outline-2 focus-visible:outline-thb06-acc focus-visible:outline-offset-2"><svg viewBox="0 0 24 24" class="w-4.5 h-4.5 fill-current" aria-hidden="true"><path d="M5 19a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"/><path d="M4 11a9 9 0 0 1 9 9M4 5a15 15 0 0 1 15 15" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg></a>
</div>
<button type="button" class="min-h-12 rounded-xl border-0 bg-thb06-ink font-thb06-sans text-sm font-bold text-thb06-bg cursor-pointer transition-[background] duration-200 hover:bg-thb06-acc focus-visible:outline-2 focus-visible:outline-thb06-acc focus-visible:outline-offset-2">Get the newsletter</button>
</footer>
</aside>
</div>
</section><section class="thb-06 w-full min-h-svh grid justify-center content-start bg-thb06-bg font-thb06-sans text-thb06-ink px-5 py-9" aria-label="Hamburger menu with search and social links demo">
<div class="group relative w-[min(400px,88vw)] h-140 rounded-3xl overflow-hidden bg-thb06-bg border border-thb06-edge">
<header class="flex items-center gap-3 h-16.5 px-4.5 bg-thb06-panel border-b border-thb06-edge">
<button type="button" aria-expanded="false" aria-controls="thb06-drawer" aria-label="Open menu" class="grid place-items-center w-11 h-11 -ml-2 rounded-xl border-0 bg-transparent text-thb06-ink cursor-pointer transition-[background] duration-200 hover:bg-thb06-hover focus-visible:outline-2 focus-visible:outline-thb06-acc focus-visible:outline-offset-2">
<span class="relative block w-5 h-3.5" aria-hidden="true">
<i class="absolute left-0 top-0 w-5 h-0.5 rounded-sm bg-current"></i>
<i class="absolute left-0 top-1.5 w-5 h-0.5 rounded-sm bg-current"></i>
<i class="absolute left-0 top-3 w-5 h-0.5 rounded-sm bg-current"></i>
</span>
</button>
<span class="text-[17px] font-extrabold tracking-[0.14em]">KIOSK<i class="not-italic font-normal tracking-normal text-thb06-acc">daily</i></span>
<span class="relative ml-auto text-thb06-ink" aria-hidden="true">
<svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"><path d="M4.5 7h15L18 20H6Z"/><path d="M8.5 7a3.5 3.5 0 0 1 7 0"/></svg>
<b class="absolute -top-1.75 -right-2.25 px-1.5 py-px rounded-full bg-thb06-acc text-white text-[9.5px] font-bold">2</b>
</span>
</header>
<div class="grid gap-3.25 p-4.5" aria-hidden="true">
<div class="h-45 rounded-[14px] bg-linear-[145deg,oklch(0.9_0.03_50),oklch(0.85_0.055_25)]"></div>
<div class="h-2.75 w-[86%] rounded-full bg-thb06-line"></div>
<div class="h-2.75 w-[64%] rounded-full bg-thb06-line"></div>
</div>
<button type="button" tabindex="-1" aria-hidden="true" class="absolute inset-0 z-2 border-0 p-0 cursor-pointer opacity-0 invisible bg-[oklch(0.22_0.02_40/0.42)] backdrop-blur-[2px] [transition:opacity_.3s,visibility_0s_.3s] group-data-open:opacity-100 group-data-open:visible group-data-open:[transition:opacity_.3s,visibility_0s_0s]"></button>
<aside id="thb06-drawer" aria-label="Menu" class="absolute inset-y-0 left-0 z-3 grid grid-rows-[auto_1fr_auto] w-[min(88%,330px)] bg-thb06-panel shadow-[24px_0_48px_-24px_oklch(0.25_0.03_40/0.45)] -translate-x-[102%] invisible [transition:translate_.42s_var(--ease-thb06),visibility_0s_.42s] group-data-open:translate-x-0 group-data-open:visible group-data-open:[transition:translate_.42s_var(--ease-thb06),visibility_0s_0s] motion-reduce:[transition:opacity_.15s,visibility_0s_.15s]">
<div class="flex items-center gap-2.5 px-4 pt-4 pb-3">
<form role="search" class="flex flex-1 items-center gap-2.25 min-h-11 px-3.5 rounded-xl border-[1.5px] border-thb06-edge text-thb06-mut transition-[border-color,color] duration-200 focus-within:border-thb06-acc focus-within:text-thb06-acc">
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><circle cx="11" cy="11" r="7"/><path d="m20 20-3.5-3.5"/></svg>
<input type="search" placeholder="Search stories, topics…" aria-label="Search" class="flex-1 min-w-0 border-0 outline-none bg-transparent font-thb06-sans text-sm text-thb06-ink">
</form>
<button type="button" aria-label="Close menu" class="grid place-items-center shrink-0 w-11 h-11 rounded-xl border-[1.5px] border-thb06-edge bg-thb06-panel text-thb06-ink cursor-pointer transition-[background] duration-200 hover:bg-thb06-hover focus-visible:outline-2 focus-visible:outline-thb06-acc focus-visible:outline-offset-2">
<svg viewBox="0 0 24 24" width="15" height="15" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" aria-hidden="true"><path d="m6 6 12 12M18 6 6 18"/></svg>
</button>
</div>
<nav aria-label="Sections" class="flex flex-col min-h-0 overflow-auto overscroll-contain px-2.5 py-1">
<a href="#latest" class="flex items-center justify-between gap-3 min-h-12.5 px-3 rounded-[11px] no-underline text-[15.5px] font-bold tracking-[-0.01em] text-thb06-ink transition-[background,color] duration-150 hover:bg-thb06-hover hover:text-thb06-acc focus-visible:outline-2 focus-visible:outline-thb06-acc focus-visible:-outline-offset-2">Latest<span class="text-[11.5px] font-semibold text-thb06-mut tabular-nums">128</span></a>
<a href="#tech" class="flex items-center justify-between gap-3 min-h-12.5 px-3 rounded-[11px] no-underline text-[15.5px] font-bold tracking-[-0.01em] text-thb06-ink transition-[background,color] duration-150 hover:bg-thb06-hover hover:text-thb06-acc focus-visible:outline-2 focus-visible:outline-thb06-acc focus-visible:-outline-offset-2">Technology<span class="text-[11.5px] font-semibold text-thb06-mut tabular-nums">41</span></a>
<a href="#design" class="flex items-center justify-between gap-3 min-h-12.5 px-3 rounded-[11px] no-underline text-[15.5px] font-bold tracking-[-0.01em] text-thb06-ink transition-[background,color] duration-150 hover:bg-thb06-hover hover:text-thb06-acc focus-visible:outline-2 focus-visible:outline-thb06-acc focus-visible:-outline-offset-2">Design<span class="text-[11.5px] font-semibold text-thb06-mut tabular-nums">27</span></a>
<a href="#culture" class="flex items-center justify-between gap-3 min-h-12.5 px-3 rounded-[11px] no-underline text-[15.5px] font-bold tracking-[-0.01em] text-thb06-ink transition-[background,color] duration-150 hover:bg-thb06-hover hover:text-thb06-acc focus-visible:outline-2 focus-visible:outline-thb06-acc focus-visible:-outline-offset-2">Culture<b class="px-2 py-0.75 rounded-full bg-thb06-acc text-white text-[10px] font-extrabold tracking-[0.08em] uppercase">New</b></a>
<a href="#podcasts" class="flex items-center justify-between gap-3 min-h-12.5 px-3 rounded-[11px] no-underline text-[15.5px] font-bold tracking-[-0.01em] text-thb06-ink transition-[background,color] duration-150 hover:bg-thb06-hover hover:text-thb06-acc focus-visible:outline-2 focus-visible:outline-thb06-acc focus-visible:-outline-offset-2">Podcasts<span class="text-[11.5px] font-semibold text-thb06-mut tabular-nums">12</span></a>
<a href="#archive" class="flex items-center justify-between gap-3 min-h-12.5 px-3 rounded-[11px] no-underline text-[15.5px] font-bold tracking-[-0.01em] text-thb06-ink transition-[background,color] duration-150 hover:bg-thb06-hover hover:text-thb06-acc focus-visible:outline-2 focus-visible:outline-thb06-acc focus-visible:-outline-offset-2">Archive</a>
</nav>
<footer class="grid gap-3 px-4 pt-3.5 pb-4.5 border-t border-thb06-edge">
<div class="flex gap-2">
<a href="#x" aria-label="Follow on X" class="grid place-items-center w-11 h-11 rounded-xl border-[1.5px] border-thb06-edge text-thb06-ink transition-[border-color,color,translate] duration-200 hover:border-thb06-acc hover:text-thb06-acc hover:-translate-y-0.5 focus-visible:border-thb06-acc focus-visible:text-thb06-acc focus-visible:outline-2 focus-visible:outline-thb06-acc focus-visible:outline-offset-2"><svg viewBox="0 0 24 24" class="w-4.5 h-4.5 fill-current" aria-hidden="true"><path d="M4 4l7.2 9.3L4.4 20h2.1l5.6-5.5L16.8 20H20l-7.5-9.7L18.9 4h-2.1l-5.2 5.1L7.2 4H4Z"/></svg></a>
<a href="#instagram" aria-label="Follow on Instagram" class="grid place-items-center w-11 h-11 rounded-xl border-[1.5px] border-thb06-edge text-thb06-ink transition-[border-color,color,translate] duration-200 hover:border-thb06-acc hover:text-thb06-acc hover:-translate-y-0.5 focus-visible:border-thb06-acc focus-visible:text-thb06-acc focus-visible:outline-2 focus-visible:outline-thb06-acc focus-visible:outline-offset-2"><svg viewBox="0 0 24 24" class="w-4.5 h-4.5 fill-current" aria-hidden="true"><rect x="3.5" y="3.5" width="17" height="17" rx="4.5" fill="none" stroke="currentColor" stroke-width="1.8"/><circle cx="12" cy="12" r="4" fill="none" stroke="currentColor" stroke-width="1.8"/><circle cx="17.2" cy="6.8" r="1.3"/></svg></a>
<a href="#youtube" aria-label="Subscribe on YouTube" class="grid place-items-center w-11 h-11 rounded-xl border-[1.5px] border-thb06-edge text-thb06-ink transition-[border-color,color,translate] duration-200 hover:border-thb06-acc hover:text-thb06-acc hover:-translate-y-0.5 focus-visible:border-thb06-acc focus-visible:text-thb06-acc focus-visible:outline-2 focus-visible:outline-thb06-acc focus-visible:outline-offset-2"><svg viewBox="0 0 24 24" class="w-4.5 h-4.5 fill-current" aria-hidden="true"><rect x="2.5" y="6" width="19" height="12" rx="3.5" fill="none" stroke="currentColor" stroke-width="1.8"/><path d="M10.5 9.8v4.4l4-2.2Z"/></svg></a>
<a href="#rss" aria-label="RSS feed" class="grid place-items-center w-11 h-11 rounded-xl border-[1.5px] border-thb06-edge text-thb06-ink transition-[border-color,color,translate] duration-200 hover:border-thb06-acc hover:text-thb06-acc hover:-translate-y-0.5 focus-visible:border-thb06-acc focus-visible:text-thb06-acc focus-visible:outline-2 focus-visible:outline-thb06-acc focus-visible:outline-offset-2"><svg viewBox="0 0 24 24" class="w-4.5 h-4.5 fill-current" aria-hidden="true"><path d="M5 19a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"/><path d="M4 11a9 9 0 0 1 9 9M4 5a15 15 0 0 1 15 15" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg></a>
</div>
<button type="button" class="min-h-12 rounded-xl border-0 bg-thb06-ink font-thb06-sans text-sm font-bold text-thb06-bg cursor-pointer transition-[background] duration-200 hover:bg-thb06-acc focus-visible:outline-2 focus-visible:outline-thb06-acc focus-visible:outline-offset-2">Get the newsletter</button>
</footer>
</aside>
</div>
</section>@import "tailwindcss";
@theme {
--color-thb06-bg: #fbfaf7;
--color-thb06-bg: oklch(0.975 0.006 70);
--color-thb06-panel: #ffffff;
--color-thb06-panel: oklch(1 0 0);
--color-thb06-hover: #f4f2ed;
--color-thb06-hover: oklch(0.96 0.008 70);
--color-thb06-edge: #e3e0d9;
--color-thb06-edge: oklch(0.89 0.01 70);
--color-thb06-line: #e7e4dd;
--color-thb06-line: oklch(0.9 0.008 70);
--color-thb06-ink: #35302b;
--color-thb06-ink: oklch(0.23 0.015 50);
--color-thb06-mut: #7b7469;
--color-thb06-mut: oklch(0.54 0.015 50);
--color-thb06-acc: #cf3d24;
--color-thb06-acc: oklch(0.6 0.19 25);
--font-thb06-sans: 'Space Grotesk', system-ui, sans-serif;
--font-thb06-mono: 'JetBrains Mono', ui-monospace, monospace;
--ease-thb06: cubic-bezier(0.32, 0.72, 0.28, 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-06 {
width: 100%;
min-height: 100svh;
}@import "tailwindcss";
@theme {
--color-thb06-bg: #fbfaf7;
--color-thb06-bg: oklch(0.975 0.006 70);
--color-thb06-panel: #ffffff;
--color-thb06-panel: oklch(1 0 0);
--color-thb06-hover: #f4f2ed;
--color-thb06-hover: oklch(0.96 0.008 70);
--color-thb06-edge: #e3e0d9;
--color-thb06-edge: oklch(0.89 0.01 70);
--color-thb06-line: #e7e4dd;
--color-thb06-line: oklch(0.9 0.008 70);
--color-thb06-ink: #35302b;
--color-thb06-ink: oklch(0.23 0.015 50);
--color-thb06-mut: #7b7469;
--color-thb06-mut: oklch(0.54 0.015 50);
--color-thb06-acc: #cf3d24;
--color-thb06-acc: oklch(0.6 0.19 25);
--font-thb06-sans: 'Space Grotesk', system-ui, sans-serif;
--font-thb06-mono: 'JetBrains Mono', ui-monospace, monospace;
--ease-thb06: cubic-bezier(0.32, 0.72, 0.28, 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-06 {
width: 100%;
min-height: 100svh;
}(function () {
document.querySelectorAll('.thb-06 > .group').forEach(function (stage) {
if (stage.dataset.bound) return; stage.dataset.bound = '1';
var btn = stage.querySelector('button[aria-controls="thb06-drawer"]'),
scrim = stage.querySelector('button[aria-hidden="true"]'),
close = stage.querySelector('button[aria-label="Close menu"]'),
input = stage.querySelector('input[type="search"]');
function set(open) {
stage.toggleAttribute('data-open', open);
btn.setAttribute('aria-expanded', String(open));
if (open) input.focus({ preventScroll: true }); else btn.focus();
}
btn.addEventListener('click', function () { set(true); });
scrim.addEventListener('click', function () { set(false); });
close.addEventListener('click', function () { set(false); });
stage.addEventListener('keydown', function (e) {
if (e.key === 'Escape' && stage.hasAttribute('data-open')) set(false);
});
});
})();(function () {
document.querySelectorAll('.thb-06 > .group').forEach(function (stage) {
if (stage.dataset.bound) return; stage.dataset.bound = '1';
var btn = stage.querySelector('button[aria-controls="thb06-drawer"]'),
scrim = stage.querySelector('button[aria-hidden="true"]'),
close = stage.querySelector('button[aria-label="Close menu"]'),
input = stage.querySelector('input[type="search"]');
function set(open) {
stage.toggleAttribute('data-open', open);
btn.setAttribute('aria-expanded', String(open));
if (open) input.focus({ preventScroll: true }); else btn.focus();
}
btn.addEventListener('click', function () { set(true); });
scrim.addEventListener('click', function () { set(false); });
close.addEventListener('click', function () { set(false); });
stage.addEventListener('keydown', function (e) {
if (e.key === 'Escape' && stage.hasAttribute('data-open')) set(false);
});
});
})();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-thb06-bg: #fbfaf7;
--color-thb06-bg: oklch(0.975 0.006 70);
--color-thb06-panel: #ffffff;
--color-thb06-panel: oklch(1 0 0);
--color-thb06-hover: #f4f2ed;
--color-thb06-hover: oklch(0.96 0.008 70);
--color-thb06-edge: #e3e0d9;
--color-thb06-edge: oklch(0.89 0.01 70);
--color-thb06-line: #e7e4dd;
--color-thb06-line: oklch(0.9 0.008 70);
--color-thb06-ink: #35302b;
--color-thb06-ink: oklch(0.23 0.015 50);
--color-thb06-mut: #7b7469;
--color-thb06-mut: oklch(0.54 0.015 50);
--color-thb06-acc: #cf3d24;
--color-thb06-acc: oklch(0.6 0.19 25);
--font-thb06-sans: 'Space Grotesk', system-ui, sans-serif;
--font-thb06-mono: 'JetBrains Mono', ui-monospace, monospace;
--ease-thb06: cubic-bezier(0.32, 0.72, 0.28, 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-06 {
width: 100%;
min-height: 100svh;
}@import "tailwindcss";
@theme {
--color-thb06-bg: #fbfaf7;
--color-thb06-bg: oklch(0.975 0.006 70);
--color-thb06-panel: #ffffff;
--color-thb06-panel: oklch(1 0 0);
--color-thb06-hover: #f4f2ed;
--color-thb06-hover: oklch(0.96 0.008 70);
--color-thb06-edge: #e3e0d9;
--color-thb06-edge: oklch(0.89 0.01 70);
--color-thb06-line: #e7e4dd;
--color-thb06-line: oklch(0.9 0.008 70);
--color-thb06-ink: #35302b;
--color-thb06-ink: oklch(0.23 0.015 50);
--color-thb06-mut: #7b7469;
--color-thb06-mut: oklch(0.54 0.015 50);
--color-thb06-acc: #cf3d24;
--color-thb06-acc: oklch(0.6 0.19 25);
--font-thb06-sans: 'Space Grotesk', system-ui, sans-serif;
--font-thb06-mono: 'JetBrains Mono', ui-monospace, monospace;
--ease-thb06: cubic-bezier(0.32, 0.72, 0.28, 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-06 {
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=Space+Grotesk:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;600&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=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 three-row grid that makes this drawer work is now readable at a glance:
grid-rows-[auto_1fr_auto]on the drawer,min-h-0 overflow-autoon the nav. In the CSS version those two facts live in two rules three screens apart. :focus-withinbecomesfocus-within:on the search wrapper — the clearest case in the collection of a variant that reads like the sentence it implements.font-variant-numeric:tabular-numsis a real utility (tabular-nums), so the count pills need no rule at all.- Six nav links repeat an eleven-utility class list. That is the honest cost of utilities on repeated items — the fix in a real codebase is a loop or a component, never
@apply. overscroll-containandmin-w-0both survive as first-class utilities, which is lucky: they are the two easiest fixes to forget.- Left-drawer geometry becomes
left-0 -translate-x-[102%]; swappingleft-0forstart-0makes the drawer followdir="rtl"with no other edit.
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 Hamburger Menu with Integrated Search Bar & Social Links
Source: https://codefronts.com/navigation/tailwind-hamburger-menus/tailwind-responsive-hamburger-menu-search-bar-social-links/
The publisher/e-commerce drawer that carries a whole header's worth of jobs — auto-focused search, nav with counts, a New badge, a social row and a pinned newsletter CTA. The port's real content is one class list: grid grid-rows-[auto_1fr_auto] on the drawer plus min-h-0 overflow-auto on the middle row, which is the whole reason feature-rich drawers stop losing their footer.
## HTML
```html
<section class="thb-06 w-full min-h-svh grid justify-center content-start bg-thb06-bg font-thb06-sans text-thb06-ink px-5 py-9" aria-label="Hamburger menu with search and social links demo">
<div class="group relative w-[min(400px,88vw)] h-140 rounded-3xl overflow-hidden bg-thb06-bg border border-thb06-edge">
<header class="flex items-center gap-3 h-16.5 px-4.5 bg-thb06-panel border-b border-thb06-edge">
<button type="button" aria-expanded="false" aria-controls="thb06-drawer" aria-label="Open menu" class="grid place-items-center w-11 h-11 -ml-2 rounded-xl border-0 bg-transparent text-thb06-ink cursor-pointer transition-[background] duration-200 hover:bg-thb06-hover focus-visible:outline-2 focus-visible:outline-thb06-acc focus-visible:outline-offset-2">
<span class="relative block w-5 h-3.5" aria-hidden="true">
<i class="absolute left-0 top-0 w-5 h-0.5 rounded-sm bg-current"></i>
<i class="absolute left-0 top-1.5 w-5 h-0.5 rounded-sm bg-current"></i>
<i class="absolute left-0 top-3 w-5 h-0.5 rounded-sm bg-current"></i>
</span>
</button>
<span class="text-[17px] font-extrabold tracking-[0.14em]">KIOSK<i class="not-italic font-normal tracking-normal text-thb06-acc">daily</i></span>
<span class="relative ml-auto text-thb06-ink" aria-hidden="true">
<svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"><path d="M4.5 7h15L18 20H6Z"/><path d="M8.5 7a3.5 3.5 0 0 1 7 0"/></svg>
<b class="absolute -top-1.75 -right-2.25 px-1.5 py-px rounded-full bg-thb06-acc text-white text-[9.5px] font-bold">2</b>
</span>
</header>
<div class="grid gap-3.25 p-4.5" aria-hidden="true">
<div class="h-45 rounded-[14px] bg-linear-[145deg,oklch(0.9_0.03_50),oklch(0.85_0.055_25)]"></div>
<div class="h-2.75 w-[86%] rounded-full bg-thb06-line"></div>
<div class="h-2.75 w-[64%] rounded-full bg-thb06-line"></div>
</div>
<button type="button" tabindex="-1" aria-hidden="true" class="absolute inset-0 z-2 border-0 p-0 cursor-pointer opacity-0 invisible bg-[oklch(0.22_0.02_40/0.42)] backdrop-blur-[2px] [transition:opacity_.3s,visibility_0s_.3s] group-data-open:opacity-100 group-data-open:visible group-data-open:[transition:opacity_.3s,visibility_0s_0s]"></button>
<aside id="thb06-drawer" aria-label="Menu" class="absolute inset-y-0 left-0 z-3 grid grid-rows-[auto_1fr_auto] w-[min(88%,330px)] bg-thb06-panel shadow-[24px_0_48px_-24px_oklch(0.25_0.03_40/0.45)] -translate-x-[102%] invisible [transition:translate_.42s_var(--ease-thb06),visibility_0s_.42s] group-data-open:translate-x-0 group-data-open:visible group-data-open:[transition:translate_.42s_var(--ease-thb06),visibility_0s_0s] motion-reduce:[transition:opacity_.15s,visibility_0s_.15s]">
<div class="flex items-center gap-2.5 px-4 pt-4 pb-3">
<form role="search" class="flex flex-1 items-center gap-2.25 min-h-11 px-3.5 rounded-xl border-[1.5px] border-thb06-edge text-thb06-mut transition-[border-color,color] duration-200 focus-within:border-thb06-acc focus-within:text-thb06-acc">
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><circle cx="11" cy="11" r="7"/><path d="m20 20-3.5-3.5"/></svg>
<input type="search" placeholder="Search stories, topics…" aria-label="Search" class="flex-1 min-w-0 border-0 outline-none bg-transparent font-thb06-sans text-sm text-thb06-ink">
</form>
<button type="button" aria-label="Close menu" class="grid place-items-center shrink-0 w-11 h-11 rounded-xl border-[1.5px] border-thb06-edge bg-thb06-panel text-thb06-ink cursor-pointer transition-[background] duration-200 hover:bg-thb06-hover focus-visible:outline-2 focus-visible:outline-thb06-acc focus-visible:outline-offset-2">
<svg viewBox="0 0 24 24" width="15" height="15" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" aria-hidden="true"><path d="m6 6 12 12M18 6 6 18"/></svg>
</button>
</div>
<nav aria-label="Sections" class="flex flex-col min-h-0 overflow-auto overscroll-contain px-2.5 py-1">
<a href="#latest" class="flex items-center justify-between gap-3 min-h-12.5 px-3 rounded-[11px] no-underline text-[15.5px] font-bold tracking-[-0.01em] text-thb06-ink transition-[background,color] duration-150 hover:bg-thb06-hover hover:text-thb06-acc focus-visible:outline-2 focus-visible:outline-thb06-acc focus-visible:-outline-offset-2">Latest<span class="text-[11.5px] font-semibold text-thb06-mut tabular-nums">128</span></a>
<a href="#tech" class="flex items-center justify-between gap-3 min-h-12.5 px-3 rounded-[11px] no-underline text-[15.5px] font-bold tracking-[-0.01em] text-thb06-ink transition-[background,color] duration-150 hover:bg-thb06-hover hover:text-thb06-acc focus-visible:outline-2 focus-visible:outline-thb06-acc focus-visible:-outline-offset-2">Technology<span class="text-[11.5px] font-semibold text-thb06-mut tabular-nums">41</span></a>
<a href="#design" class="flex items-center justify-between gap-3 min-h-12.5 px-3 rounded-[11px] no-underline text-[15.5px] font-bold tracking-[-0.01em] text-thb06-ink transition-[background,color] duration-150 hover:bg-thb06-hover hover:text-thb06-acc focus-visible:outline-2 focus-visible:outline-thb06-acc focus-visible:-outline-offset-2">Design<span class="text-[11.5px] font-semibold text-thb06-mut tabular-nums">27</span></a>
<a href="#culture" class="flex items-center justify-between gap-3 min-h-12.5 px-3 rounded-[11px] no-underline text-[15.5px] font-bold tracking-[-0.01em] text-thb06-ink transition-[background,color] duration-150 hover:bg-thb06-hover hover:text-thb06-acc focus-visible:outline-2 focus-visible:outline-thb06-acc focus-visible:-outline-offset-2">Culture<b class="px-2 py-0.75 rounded-full bg-thb06-acc text-white text-[10px] font-extrabold tracking-[0.08em] uppercase">New</b></a>
<a href="#podcasts" class="flex items-center justify-between gap-3 min-h-12.5 px-3 rounded-[11px] no-underline text-[15.5px] font-bold tracking-[-0.01em] text-thb06-ink transition-[background,color] duration-150 hover:bg-thb06-hover hover:text-thb06-acc focus-visible:outline-2 focus-visible:outline-thb06-acc focus-visible:-outline-offset-2">Podcasts<span class="text-[11.5px] font-semibold text-thb06-mut tabular-nums">12</span></a>
<a href="#archive" class="flex items-center justify-between gap-3 min-h-12.5 px-3 rounded-[11px] no-underline text-[15.5px] font-bold tracking-[-0.01em] text-thb06-ink transition-[background,color] duration-150 hover:bg-thb06-hover hover:text-thb06-acc focus-visible:outline-2 focus-visible:outline-thb06-acc focus-visible:-outline-offset-2">Archive</a>
</nav>
<footer class="grid gap-3 px-4 pt-3.5 pb-4.5 border-t border-thb06-edge">
<div class="flex gap-2">
<a href="#x" aria-label="Follow on X" class="grid place-items-center w-11 h-11 rounded-xl border-[1.5px] border-thb06-edge text-thb06-ink transition-[border-color,color,translate] duration-200 hover:border-thb06-acc hover:text-thb06-acc hover:-translate-y-0.5 focus-visible:border-thb06-acc focus-visible:text-thb06-acc focus-visible:outline-2 focus-visible:outline-thb06-acc focus-visible:outline-offset-2"><svg viewBox="0 0 24 24" class="w-4.5 h-4.5 fill-current" aria-hidden="true"><path d="M4 4l7.2 9.3L4.4 20h2.1l5.6-5.5L16.8 20H20l-7.5-9.7L18.9 4h-2.1l-5.2 5.1L7.2 4H4Z"/></svg></a>
<a href="#instagram" aria-label="Follow on Instagram" class="grid place-items-center w-11 h-11 rounded-xl border-[1.5px] border-thb06-edge text-thb06-ink transition-[border-color,color,translate] duration-200 hover:border-thb06-acc hover:text-thb06-acc hover:-translate-y-0.5 focus-visible:border-thb06-acc focus-visible:text-thb06-acc focus-visible:outline-2 focus-visible:outline-thb06-acc focus-visible:outline-offset-2"><svg viewBox="0 0 24 24" class="w-4.5 h-4.5 fill-current" aria-hidden="true"><rect x="3.5" y="3.5" width="17" height="17" rx="4.5" fill="none" stroke="currentColor" stroke-width="1.8"/><circle cx="12" cy="12" r="4" fill="none" stroke="currentColor" stroke-width="1.8"/><circle cx="17.2" cy="6.8" r="1.3"/></svg></a>
<a href="#youtube" aria-label="Subscribe on YouTube" class="grid place-items-center w-11 h-11 rounded-xl border-[1.5px] border-thb06-edge text-thb06-ink transition-[border-color,color,translate] duration-200 hover:border-thb06-acc hover:text-thb06-acc hover:-translate-y-0.5 focus-visible:border-thb06-acc focus-visible:text-thb06-acc focus-visible:outline-2 focus-visible:outline-thb06-acc focus-visible:outline-offset-2"><svg viewBox="0 0 24 24" class="w-4.5 h-4.5 fill-current" aria-hidden="true"><rect x="2.5" y="6" width="19" height="12" rx="3.5" fill="none" stroke="currentColor" stroke-width="1.8"/><path d="M10.5 9.8v4.4l4-2.2Z"/></svg></a>
<a href="#rss" aria-label="RSS feed" class="grid place-items-center w-11 h-11 rounded-xl border-[1.5px] border-thb06-edge text-thb06-ink transition-[border-color,color,translate] duration-200 hover:border-thb06-acc hover:text-thb06-acc hover:-translate-y-0.5 focus-visible:border-thb06-acc focus-visible:text-thb06-acc focus-visible:outline-2 focus-visible:outline-thb06-acc focus-visible:outline-offset-2"><svg viewBox="0 0 24 24" class="w-4.5 h-4.5 fill-current" aria-hidden="true"><path d="M5 19a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"/><path d="M4 11a9 9 0 0 1 9 9M4 5a15 15 0 0 1 15 15" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg></a>
</div>
<button type="button" class="min-h-12 rounded-xl border-0 bg-thb06-ink font-thb06-sans text-sm font-bold text-thb06-bg cursor-pointer transition-[background] duration-200 hover:bg-thb06-acc focus-visible:outline-2 focus-visible:outline-thb06-acc focus-visible:outline-offset-2">Get the newsletter</button>
</footer>
</aside>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-thb06-bg: #fbfaf7;
--color-thb06-bg: oklch(0.975 0.006 70);
--color-thb06-panel: #ffffff;
--color-thb06-panel: oklch(1 0 0);
--color-thb06-hover: #f4f2ed;
--color-thb06-hover: oklch(0.96 0.008 70);
--color-thb06-edge: #e3e0d9;
--color-thb06-edge: oklch(0.89 0.01 70);
--color-thb06-line: #e7e4dd;
--color-thb06-line: oklch(0.9 0.008 70);
--color-thb06-ink: #35302b;
--color-thb06-ink: oklch(0.23 0.015 50);
--color-thb06-mut: #7b7469;
--color-thb06-mut: oklch(0.54 0.015 50);
--color-thb06-acc: #cf3d24;
--color-thb06-acc: oklch(0.6 0.19 25);
--font-thb06-sans: 'Space Grotesk', system-ui, sans-serif;
--font-thb06-mono: 'JetBrains Mono', ui-monospace, monospace;
--ease-thb06: cubic-bezier(0.32, 0.72, 0.28, 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-06 {
width: 100%;
min-height: 100svh;
}
```
## JavaScript
```js
(function () {
document.querySelectorAll('.thb-06 > .group').forEach(function (stage) {
if (stage.dataset.bound) return; stage.dataset.bound = '1';
var btn = stage.querySelector('button[aria-controls="thb06-drawer"]'),
scrim = stage.querySelector('button[aria-hidden="true"]'),
close = stage.querySelector('button[aria-label="Close menu"]'),
input = stage.querySelector('input[type="search"]');
function set(open) {
stage.toggleAttribute('data-open', open);
btn.setAttribute('aria-expanded', String(open));
if (open) input.focus({ preventScroll: true }); else btn.focus();
}
btn.addEventListener('click', function () { set(true); });
scrim.addEventListener('click', function () { set(false); });
close.addEventListener('click', function () { set(false); });
stage.addEventListener('keydown', function (e) {
if (e.key === 'Escape' && stage.hasAttribute('data-open')) set(false);
});
});
})();
```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 Hamburger Menu with Integrated Search Bar & Social Links
Source: https://codefronts.com/navigation/tailwind-hamburger-menus/tailwind-responsive-hamburger-menu-search-bar-social-links/
The publisher/e-commerce drawer that carries a whole header's worth of jobs — auto-focused search, nav with counts, a New badge, a social row and a pinned newsletter CTA. The port's real content is one class list: grid grid-rows-[auto_1fr_auto] on the drawer plus min-h-0 overflow-auto on the middle row, which is the whole reason feature-rich drawers stop losing their footer.
## HTML
```html
<section class="thb-06 w-full min-h-svh grid justify-center content-start bg-thb06-bg font-thb06-sans text-thb06-ink px-5 py-9" aria-label="Hamburger menu with search and social links demo">
<div class="group relative w-[min(400px,88vw)] h-140 rounded-3xl overflow-hidden bg-thb06-bg border border-thb06-edge">
<header class="flex items-center gap-3 h-16.5 px-4.5 bg-thb06-panel border-b border-thb06-edge">
<button type="button" aria-expanded="false" aria-controls="thb06-drawer" aria-label="Open menu" class="grid place-items-center w-11 h-11 -ml-2 rounded-xl border-0 bg-transparent text-thb06-ink cursor-pointer transition-[background] duration-200 hover:bg-thb06-hover focus-visible:outline-2 focus-visible:outline-thb06-acc focus-visible:outline-offset-2">
<span class="relative block w-5 h-3.5" aria-hidden="true">
<i class="absolute left-0 top-0 w-5 h-0.5 rounded-sm bg-current"></i>
<i class="absolute left-0 top-1.5 w-5 h-0.5 rounded-sm bg-current"></i>
<i class="absolute left-0 top-3 w-5 h-0.5 rounded-sm bg-current"></i>
</span>
</button>
<span class="text-[17px] font-extrabold tracking-[0.14em]">KIOSK<i class="not-italic font-normal tracking-normal text-thb06-acc">daily</i></span>
<span class="relative ml-auto text-thb06-ink" aria-hidden="true">
<svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"><path d="M4.5 7h15L18 20H6Z"/><path d="M8.5 7a3.5 3.5 0 0 1 7 0"/></svg>
<b class="absolute -top-1.75 -right-2.25 px-1.5 py-px rounded-full bg-thb06-acc text-white text-[9.5px] font-bold">2</b>
</span>
</header>
<div class="grid gap-3.25 p-4.5" aria-hidden="true">
<div class="h-45 rounded-[14px] bg-linear-[145deg,oklch(0.9_0.03_50),oklch(0.85_0.055_25)]"></div>
<div class="h-2.75 w-[86%] rounded-full bg-thb06-line"></div>
<div class="h-2.75 w-[64%] rounded-full bg-thb06-line"></div>
</div>
<button type="button" tabindex="-1" aria-hidden="true" class="absolute inset-0 z-2 border-0 p-0 cursor-pointer opacity-0 invisible bg-[oklch(0.22_0.02_40/0.42)] backdrop-blur-[2px] [transition:opacity_.3s,visibility_0s_.3s] group-data-open:opacity-100 group-data-open:visible group-data-open:[transition:opacity_.3s,visibility_0s_0s]"></button>
<aside id="thb06-drawer" aria-label="Menu" class="absolute inset-y-0 left-0 z-3 grid grid-rows-[auto_1fr_auto] w-[min(88%,330px)] bg-thb06-panel shadow-[24px_0_48px_-24px_oklch(0.25_0.03_40/0.45)] -translate-x-[102%] invisible [transition:translate_.42s_var(--ease-thb06),visibility_0s_.42s] group-data-open:translate-x-0 group-data-open:visible group-data-open:[transition:translate_.42s_var(--ease-thb06),visibility_0s_0s] motion-reduce:[transition:opacity_.15s,visibility_0s_.15s]">
<div class="flex items-center gap-2.5 px-4 pt-4 pb-3">
<form role="search" class="flex flex-1 items-center gap-2.25 min-h-11 px-3.5 rounded-xl border-[1.5px] border-thb06-edge text-thb06-mut transition-[border-color,color] duration-200 focus-within:border-thb06-acc focus-within:text-thb06-acc">
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><circle cx="11" cy="11" r="7"/><path d="m20 20-3.5-3.5"/></svg>
<input type="search" placeholder="Search stories, topics…" aria-label="Search" class="flex-1 min-w-0 border-0 outline-none bg-transparent font-thb06-sans text-sm text-thb06-ink">
</form>
<button type="button" aria-label="Close menu" class="grid place-items-center shrink-0 w-11 h-11 rounded-xl border-[1.5px] border-thb06-edge bg-thb06-panel text-thb06-ink cursor-pointer transition-[background] duration-200 hover:bg-thb06-hover focus-visible:outline-2 focus-visible:outline-thb06-acc focus-visible:outline-offset-2">
<svg viewBox="0 0 24 24" width="15" height="15" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" aria-hidden="true"><path d="m6 6 12 12M18 6 6 18"/></svg>
</button>
</div>
<nav aria-label="Sections" class="flex flex-col min-h-0 overflow-auto overscroll-contain px-2.5 py-1">
<a href="#latest" class="flex items-center justify-between gap-3 min-h-12.5 px-3 rounded-[11px] no-underline text-[15.5px] font-bold tracking-[-0.01em] text-thb06-ink transition-[background,color] duration-150 hover:bg-thb06-hover hover:text-thb06-acc focus-visible:outline-2 focus-visible:outline-thb06-acc focus-visible:-outline-offset-2">Latest<span class="text-[11.5px] font-semibold text-thb06-mut tabular-nums">128</span></a>
<a href="#tech" class="flex items-center justify-between gap-3 min-h-12.5 px-3 rounded-[11px] no-underline text-[15.5px] font-bold tracking-[-0.01em] text-thb06-ink transition-[background,color] duration-150 hover:bg-thb06-hover hover:text-thb06-acc focus-visible:outline-2 focus-visible:outline-thb06-acc focus-visible:-outline-offset-2">Technology<span class="text-[11.5px] font-semibold text-thb06-mut tabular-nums">41</span></a>
<a href="#design" class="flex items-center justify-between gap-3 min-h-12.5 px-3 rounded-[11px] no-underline text-[15.5px] font-bold tracking-[-0.01em] text-thb06-ink transition-[background,color] duration-150 hover:bg-thb06-hover hover:text-thb06-acc focus-visible:outline-2 focus-visible:outline-thb06-acc focus-visible:-outline-offset-2">Design<span class="text-[11.5px] font-semibold text-thb06-mut tabular-nums">27</span></a>
<a href="#culture" class="flex items-center justify-between gap-3 min-h-12.5 px-3 rounded-[11px] no-underline text-[15.5px] font-bold tracking-[-0.01em] text-thb06-ink transition-[background,color] duration-150 hover:bg-thb06-hover hover:text-thb06-acc focus-visible:outline-2 focus-visible:outline-thb06-acc focus-visible:-outline-offset-2">Culture<b class="px-2 py-0.75 rounded-full bg-thb06-acc text-white text-[10px] font-extrabold tracking-[0.08em] uppercase">New</b></a>
<a href="#podcasts" class="flex items-center justify-between gap-3 min-h-12.5 px-3 rounded-[11px] no-underline text-[15.5px] font-bold tracking-[-0.01em] text-thb06-ink transition-[background,color] duration-150 hover:bg-thb06-hover hover:text-thb06-acc focus-visible:outline-2 focus-visible:outline-thb06-acc focus-visible:-outline-offset-2">Podcasts<span class="text-[11.5px] font-semibold text-thb06-mut tabular-nums">12</span></a>
<a href="#archive" class="flex items-center justify-between gap-3 min-h-12.5 px-3 rounded-[11px] no-underline text-[15.5px] font-bold tracking-[-0.01em] text-thb06-ink transition-[background,color] duration-150 hover:bg-thb06-hover hover:text-thb06-acc focus-visible:outline-2 focus-visible:outline-thb06-acc focus-visible:-outline-offset-2">Archive</a>
</nav>
<footer class="grid gap-3 px-4 pt-3.5 pb-4.5 border-t border-thb06-edge">
<div class="flex gap-2">
<a href="#x" aria-label="Follow on X" class="grid place-items-center w-11 h-11 rounded-xl border-[1.5px] border-thb06-edge text-thb06-ink transition-[border-color,color,translate] duration-200 hover:border-thb06-acc hover:text-thb06-acc hover:-translate-y-0.5 focus-visible:border-thb06-acc focus-visible:text-thb06-acc focus-visible:outline-2 focus-visible:outline-thb06-acc focus-visible:outline-offset-2"><svg viewBox="0 0 24 24" class="w-4.5 h-4.5 fill-current" aria-hidden="true"><path d="M4 4l7.2 9.3L4.4 20h2.1l5.6-5.5L16.8 20H20l-7.5-9.7L18.9 4h-2.1l-5.2 5.1L7.2 4H4Z"/></svg></a>
<a href="#instagram" aria-label="Follow on Instagram" class="grid place-items-center w-11 h-11 rounded-xl border-[1.5px] border-thb06-edge text-thb06-ink transition-[border-color,color,translate] duration-200 hover:border-thb06-acc hover:text-thb06-acc hover:-translate-y-0.5 focus-visible:border-thb06-acc focus-visible:text-thb06-acc focus-visible:outline-2 focus-visible:outline-thb06-acc focus-visible:outline-offset-2"><svg viewBox="0 0 24 24" class="w-4.5 h-4.5 fill-current" aria-hidden="true"><rect x="3.5" y="3.5" width="17" height="17" rx="4.5" fill="none" stroke="currentColor" stroke-width="1.8"/><circle cx="12" cy="12" r="4" fill="none" stroke="currentColor" stroke-width="1.8"/><circle cx="17.2" cy="6.8" r="1.3"/></svg></a>
<a href="#youtube" aria-label="Subscribe on YouTube" class="grid place-items-center w-11 h-11 rounded-xl border-[1.5px] border-thb06-edge text-thb06-ink transition-[border-color,color,translate] duration-200 hover:border-thb06-acc hover:text-thb06-acc hover:-translate-y-0.5 focus-visible:border-thb06-acc focus-visible:text-thb06-acc focus-visible:outline-2 focus-visible:outline-thb06-acc focus-visible:outline-offset-2"><svg viewBox="0 0 24 24" class="w-4.5 h-4.5 fill-current" aria-hidden="true"><rect x="2.5" y="6" width="19" height="12" rx="3.5" fill="none" stroke="currentColor" stroke-width="1.8"/><path d="M10.5 9.8v4.4l4-2.2Z"/></svg></a>
<a href="#rss" aria-label="RSS feed" class="grid place-items-center w-11 h-11 rounded-xl border-[1.5px] border-thb06-edge text-thb06-ink transition-[border-color,color,translate] duration-200 hover:border-thb06-acc hover:text-thb06-acc hover:-translate-y-0.5 focus-visible:border-thb06-acc focus-visible:text-thb06-acc focus-visible:outline-2 focus-visible:outline-thb06-acc focus-visible:outline-offset-2"><svg viewBox="0 0 24 24" class="w-4.5 h-4.5 fill-current" aria-hidden="true"><path d="M5 19a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"/><path d="M4 11a9 9 0 0 1 9 9M4 5a15 15 0 0 1 15 15" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg></a>
</div>
<button type="button" class="min-h-12 rounded-xl border-0 bg-thb06-ink font-thb06-sans text-sm font-bold text-thb06-bg cursor-pointer transition-[background] duration-200 hover:bg-thb06-acc focus-visible:outline-2 focus-visible:outline-thb06-acc focus-visible:outline-offset-2">Get the newsletter</button>
</footer>
</aside>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-thb06-bg: #fbfaf7;
--color-thb06-bg: oklch(0.975 0.006 70);
--color-thb06-panel: #ffffff;
--color-thb06-panel: oklch(1 0 0);
--color-thb06-hover: #f4f2ed;
--color-thb06-hover: oklch(0.96 0.008 70);
--color-thb06-edge: #e3e0d9;
--color-thb06-edge: oklch(0.89 0.01 70);
--color-thb06-line: #e7e4dd;
--color-thb06-line: oklch(0.9 0.008 70);
--color-thb06-ink: #35302b;
--color-thb06-ink: oklch(0.23 0.015 50);
--color-thb06-mut: #7b7469;
--color-thb06-mut: oklch(0.54 0.015 50);
--color-thb06-acc: #cf3d24;
--color-thb06-acc: oklch(0.6 0.19 25);
--font-thb06-sans: 'Space Grotesk', system-ui, sans-serif;
--font-thb06-mono: 'JetBrains Mono', ui-monospace, monospace;
--ease-thb06: cubic-bezier(0.32, 0.72, 0.28, 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-06 {
width: 100%;
min-height: 100svh;
}
```
## JavaScript
```js
(function () {
document.querySelectorAll('.thb-06 > .group').forEach(function (stage) {
if (stage.dataset.bound) return; stage.dataset.bound = '1';
var btn = stage.querySelector('button[aria-controls="thb06-drawer"]'),
scrim = stage.querySelector('button[aria-hidden="true"]'),
close = stage.querySelector('button[aria-label="Close menu"]'),
input = stage.querySelector('input[type="search"]');
function set(open) {
stage.toggleAttribute('data-open', open);
btn.setAttribute('aria-expanded', String(open));
if (open) input.focus({ preventScroll: true }); else btn.focus();
}
btn.addEventListener('click', function () { set(true); });
scrim.addEventListener('click', function () { set(false); });
close.addEventListener('click', function () { set(false); });
stage.addEventListener('keydown', function (e) {
if (e.key === 'Escape' && stage.hasAttribute('data-open')) set(false);
});
});
})();
```How this works
Feature-rich drawers die by overflow, and the fix is three utilities.
<aside class="grid grid-rows-[auto_1fr_auto] …">
<div>search + close</div> <!-- auto -->
<nav class="min-h-0 overflow-auto overscroll-contain">…</nav>
<footer>socials + CTA</footer> <!-- auto -->
</aside>min-h-0 is the line everyone forgets: grid children default to min-height:auto and refuse to shrink below content height, so without it a long nav list stretches the drawer and pushes the CTA below the fold instead of scrolling. overscroll-contain stops a flicked list from momentum-scrolling the page behind.
Search as a landmark, not a box. It is a real <form role="search"> so screen-reader users can jump to it directly, and the wrapper — not the input — carries the border, lit by focus-within:. The input keeps outline-none only because its parent shows the focus state; that is the one legitimate use of removing an outline.
Focus goes where the intent is. Opening calls input.focus({preventScroll:true}); the option is what stops mobile Safari yanking the page as the keyboard appears. Retail wants the search focused, content sites often prefer the first link — one selector in the script.
The shell is demo 04's engine. Translate, delayed visibility, real-button scrim. Proving the shell and the content strategy are independent layers is the point of having both demos.
Make it yours
- Focus target on open is one selector in the script — the search input, or the first nav link.
- Social row: each icon is an inline
<svg>in aw-11 h-11box. Add or remove links freely; keep the box and thearia-label. - Counts and the New badge are presentational spans. Server-render them; screen readers read them inline with the link name, which is correct here.
- Drawer side:
left-0 -translate-x-[102%]→right-0 translate-x-[102%]. For RTL, swapleft-0forstart-0and it followsdirautomatically. - Retheme through
--color-thb06-acc; the cart badge, the New pill, the search focus state and the CTA hover all read it.
Gotchas — read before shipping
- Without
min-h-0on the scrolling row, long nav lists silently push the social row below the fold. This is the single most common feature-drawer bug and it has no visual warning. - Focusing an input on open raises the mobile keyboard, which resizes the visual viewport and can jump the drawer — use
interactive-widget=resizes-contentin the viewport meta, or focus only at desktop widths. - Icon-only social links without
aria-labelannounce as “link, graphic”. Five seconds to fix, and present in most shipped drawers. - Keep the CTA inside the drawer's grid, never
fixed: the drawer's transform makes it the containing block, so a fixed child anchors to the drawer, not the viewport. overflow-autoon the nav needs the drawer to be a real grid. Put it on a flex child withoutmin-h-0and you get the same silent stretch.- The search input needs
min-w-0inside its flex row, or a long placeholder blows the field past the drawer width.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
Grid row templates, min-height:0 and overscroll-behavior are Baseline everywhere; the floor quoted here is Tailwind v4's own generated sheet.