27 / 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
Brutalist Design Bordered Tailwind Hamburger Menu
Neo-brutalism with its rules intact: 3px black borders on everything, hard offset shadows that do not blur, one shrieking yellow, uppercase mono type — and motion that CUTS instead of eases, because in this dialect a transition curve is a lie. The press is the port's neatest line: the plate travels exactly its shadow's offset and lands flat, which is two utilities sitting next to each other.
Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time
Untitled UI React · Affiliate link
The code
<section class="thb-27 w-full min-h-svh grid justify-center content-start bg-thb27-paper font-thb27-mono text-thb27-ink px-5 py-9" aria-label="Brutalist bordered menu demo">
<div class="group relative flex flex-col w-[min(400px,88vw)] h-140 overflow-hidden border-[3px] border-thb27-ink bg-thb27-paper shadow-[8px_8px_0_var(--color-thb27-ink)] [background-image:radial-gradient(oklch(0.18_0.01_90/0.14)_1.2px,transparent_1.3px)] [background-size:18px_18px]">
<input type="checkbox" id="thb27-t" class="peer absolute w-px h-px overflow-hidden whitespace-nowrap [clip-path:inset(50%)]">
<header class="relative z-2 flex items-center justify-between p-3.5 border-b-[3px] border-thb27-ink bg-thb27-paper">
<span class="text-base font-bold tracking-[0.04em]">RAW—GOODS<i class="not-italic align-super text-[10px]" aria-hidden="true">®</i></span>
<label for="thb27-t" class="flex items-center gap-2.5 min-h-11.5 px-3.5 border-[3px] border-thb27-ink bg-thb27-acc cursor-pointer select-none shadow-[6px_6px_0_var(--color-thb27-ink)] transition-[translate,box-shadow,background] duration-[60ms] ease-linear hover:bg-thb27-acc2 peer-focus-visible:outline-3 peer-focus-visible:outline-thb27-ink peer-focus-visible:outline-offset-3 group-has-checked:translate-x-1.5 group-has-checked:translate-y-1.5 group-has-checked:shadow-[0_0_0_var(--color-thb27-ink)]">
<span class="relative block w-5 h-3.5" aria-hidden="true">
<i class="absolute left-0 top-0 w-5 h-[3px] bg-thb27-ink transition-[translate,rotate] duration-[60ms] ease-linear group-has-checked:translate-y-[5.5px] group-has-checked:rotate-45"></i>
<i class="absolute left-0 top-[5.5px] w-5 h-[3px] bg-thb27-ink transition-[opacity] duration-[60ms] ease-linear group-has-checked:opacity-0"></i>
<i class="absolute left-0 top-[11px] w-5 h-[3px] bg-thb27-ink transition-[translate,rotate] duration-[60ms] ease-linear group-has-checked:-translate-y-[5.5px] group-has-checked:-rotate-45"></i>
</span>
<span class="text-xs font-bold tracking-[0.08em] group-has-checked:hidden" aria-hidden="true">MENU</span>
<span class="hidden text-xs font-bold tracking-[0.08em] group-has-checked:block" aria-hidden="true">CLOSE</span>
</label>
</header>
<nav aria-label="Site" class="absolute inset-x-0 top-[79px] bottom-10 z-1 hidden flex-col bg-thb27-paper border-b-[3px] border-thb27-ink group-has-checked:flex">
<div class="border-b-[3px] border-thb27-ink"><a href="#shop" class="group/r flex items-center gap-3.5 min-h-16 px-4.5 text-[15px] font-bold tracking-[0.06em] text-thb27-ink no-underline hover:bg-thb27-ink hover:text-thb27-paper focus-visible:bg-thb27-ink focus-visible:text-thb27-paper focus-visible:outline-3 focus-visible:outline-thb27-acc focus-visible:-outline-offset-6"><b class="px-1.5 py-0.5 border-2 border-thb27-ink text-[11px] group-hover/r:border-thb27-paper group-focus-visible/r:border-thb27-paper">01</b>SHOP ALL<span class="ml-auto text-lg" aria-hidden="true">→</span></a></div>
<div class="border-b-[3px] border-thb27-ink"><a href="#drops" class="group/r flex items-center gap-3.5 min-h-16 px-4.5 text-[15px] font-bold tracking-[0.06em] text-thb27-ink no-underline hover:bg-thb27-ink hover:text-thb27-paper focus-visible:bg-thb27-ink focus-visible:text-thb27-paper focus-visible:outline-3 focus-visible:outline-thb27-acc focus-visible:-outline-offset-6"><b class="px-1.5 py-0.5 border-2 border-thb27-ink text-[11px] group-hover/r:border-thb27-paper group-focus-visible/r:border-thb27-paper">02</b>DROPS<span class="ml-auto text-lg" aria-hidden="true">→</span></a></div>
<div class="border-b-[3px] border-thb27-ink"><a href="#manifesto" class="group/r flex items-center gap-3.5 min-h-16 px-4.5 text-[15px] font-bold tracking-[0.06em] text-thb27-ink no-underline hover:bg-thb27-ink hover:text-thb27-paper focus-visible:bg-thb27-ink focus-visible:text-thb27-paper focus-visible:outline-3 focus-visible:outline-thb27-acc focus-visible:-outline-offset-6"><b class="px-1.5 py-0.5 border-2 border-thb27-ink text-[11px] group-hover/r:border-thb27-paper group-focus-visible/r:border-thb27-paper">03</b>MANIFESTO<span class="ml-auto text-lg" aria-hidden="true">→</span></a></div>
<div class="border-b-[3px] border-thb27-ink"><a href="#faq" class="group/r flex items-center gap-3.5 min-h-16 px-4.5 text-[15px] font-bold tracking-[0.06em] text-thb27-ink no-underline hover:bg-thb27-ink hover:text-thb27-paper focus-visible:bg-thb27-ink focus-visible:text-thb27-paper focus-visible:outline-3 focus-visible:outline-thb27-acc focus-visible:-outline-offset-6"><b class="px-1.5 py-0.5 border-2 border-thb27-ink text-[11px] group-hover/r:border-thb27-paper group-focus-visible/r:border-thb27-paper">04</b>FAQ<span class="ml-auto text-lg" aria-hidden="true">→</span></a></div>
</nav>
<div class="flex-1 grid content-start gap-4.5 p-5.5" aria-hidden="true">
<div class="w-max -rotate-1.5 px-4 py-3 border-[3px] border-thb27-ink bg-thb27-acc text-xs font-bold leading-[1.7] tracking-[0.06em] shadow-[6px_6px_0_var(--color-thb27-ink)]">EST. 2026<br>NO COOKIES<br>NO TRACKING</div>
<div class="h-37.5 border-[3px] border-thb27-ink [background:repeating-linear-gradient(-45deg,var(--color-thb27-paper)_0_12px,oklch(0.18_0.01_90/0.12)_12px_24px)]"></div>
</div>
<div class="mt-auto overflow-hidden py-2.25 border-t-[3px] border-thb27-ink bg-thb27-ink text-thb27-paper" aria-hidden="true">
<div class="flex w-max animate-thb27-tape motion-reduce:animate-none">
<span class="whitespace-nowrap text-[11.5px] font-bold tracking-[0.14em]">FREE SHIPPING OVER $80 ★ PRESS THE PLATE ★ EVERYTHING HAS A BORDER ★ </span>
<span class="whitespace-nowrap text-[11.5px] font-bold tracking-[0.14em]">FREE SHIPPING OVER $80 ★ PRESS THE PLATE ★ EVERYTHING HAS A BORDER ★ </span>
</div>
</div>
</div>
</section><section class="thb-27 w-full min-h-svh grid justify-center content-start bg-thb27-paper font-thb27-mono text-thb27-ink px-5 py-9" aria-label="Brutalist bordered menu demo">
<div class="group relative flex flex-col w-[min(400px,88vw)] h-140 overflow-hidden border-[3px] border-thb27-ink bg-thb27-paper shadow-[8px_8px_0_var(--color-thb27-ink)] [background-image:radial-gradient(oklch(0.18_0.01_90/0.14)_1.2px,transparent_1.3px)] [background-size:18px_18px]">
<input type="checkbox" id="thb27-t" class="peer absolute w-px h-px overflow-hidden whitespace-nowrap [clip-path:inset(50%)]">
<header class="relative z-2 flex items-center justify-between p-3.5 border-b-[3px] border-thb27-ink bg-thb27-paper">
<span class="text-base font-bold tracking-[0.04em]">RAW—GOODS<i class="not-italic align-super text-[10px]" aria-hidden="true">®</i></span>
<label for="thb27-t" class="flex items-center gap-2.5 min-h-11.5 px-3.5 border-[3px] border-thb27-ink bg-thb27-acc cursor-pointer select-none shadow-[6px_6px_0_var(--color-thb27-ink)] transition-[translate,box-shadow,background] duration-[60ms] ease-linear hover:bg-thb27-acc2 peer-focus-visible:outline-3 peer-focus-visible:outline-thb27-ink peer-focus-visible:outline-offset-3 group-has-checked:translate-x-1.5 group-has-checked:translate-y-1.5 group-has-checked:shadow-[0_0_0_var(--color-thb27-ink)]">
<span class="relative block w-5 h-3.5" aria-hidden="true">
<i class="absolute left-0 top-0 w-5 h-[3px] bg-thb27-ink transition-[translate,rotate] duration-[60ms] ease-linear group-has-checked:translate-y-[5.5px] group-has-checked:rotate-45"></i>
<i class="absolute left-0 top-[5.5px] w-5 h-[3px] bg-thb27-ink transition-[opacity] duration-[60ms] ease-linear group-has-checked:opacity-0"></i>
<i class="absolute left-0 top-[11px] w-5 h-[3px] bg-thb27-ink transition-[translate,rotate] duration-[60ms] ease-linear group-has-checked:-translate-y-[5.5px] group-has-checked:-rotate-45"></i>
</span>
<span class="text-xs font-bold tracking-[0.08em] group-has-checked:hidden" aria-hidden="true">MENU</span>
<span class="hidden text-xs font-bold tracking-[0.08em] group-has-checked:block" aria-hidden="true">CLOSE</span>
</label>
</header>
<nav aria-label="Site" class="absolute inset-x-0 top-[79px] bottom-10 z-1 hidden flex-col bg-thb27-paper border-b-[3px] border-thb27-ink group-has-checked:flex">
<div class="border-b-[3px] border-thb27-ink"><a href="#shop" class="group/r flex items-center gap-3.5 min-h-16 px-4.5 text-[15px] font-bold tracking-[0.06em] text-thb27-ink no-underline hover:bg-thb27-ink hover:text-thb27-paper focus-visible:bg-thb27-ink focus-visible:text-thb27-paper focus-visible:outline-3 focus-visible:outline-thb27-acc focus-visible:-outline-offset-6"><b class="px-1.5 py-0.5 border-2 border-thb27-ink text-[11px] group-hover/r:border-thb27-paper group-focus-visible/r:border-thb27-paper">01</b>SHOP ALL<span class="ml-auto text-lg" aria-hidden="true">→</span></a></div>
<div class="border-b-[3px] border-thb27-ink"><a href="#drops" class="group/r flex items-center gap-3.5 min-h-16 px-4.5 text-[15px] font-bold tracking-[0.06em] text-thb27-ink no-underline hover:bg-thb27-ink hover:text-thb27-paper focus-visible:bg-thb27-ink focus-visible:text-thb27-paper focus-visible:outline-3 focus-visible:outline-thb27-acc focus-visible:-outline-offset-6"><b class="px-1.5 py-0.5 border-2 border-thb27-ink text-[11px] group-hover/r:border-thb27-paper group-focus-visible/r:border-thb27-paper">02</b>DROPS<span class="ml-auto text-lg" aria-hidden="true">→</span></a></div>
<div class="border-b-[3px] border-thb27-ink"><a href="#manifesto" class="group/r flex items-center gap-3.5 min-h-16 px-4.5 text-[15px] font-bold tracking-[0.06em] text-thb27-ink no-underline hover:bg-thb27-ink hover:text-thb27-paper focus-visible:bg-thb27-ink focus-visible:text-thb27-paper focus-visible:outline-3 focus-visible:outline-thb27-acc focus-visible:-outline-offset-6"><b class="px-1.5 py-0.5 border-2 border-thb27-ink text-[11px] group-hover/r:border-thb27-paper group-focus-visible/r:border-thb27-paper">03</b>MANIFESTO<span class="ml-auto text-lg" aria-hidden="true">→</span></a></div>
<div class="border-b-[3px] border-thb27-ink"><a href="#faq" class="group/r flex items-center gap-3.5 min-h-16 px-4.5 text-[15px] font-bold tracking-[0.06em] text-thb27-ink no-underline hover:bg-thb27-ink hover:text-thb27-paper focus-visible:bg-thb27-ink focus-visible:text-thb27-paper focus-visible:outline-3 focus-visible:outline-thb27-acc focus-visible:-outline-offset-6"><b class="px-1.5 py-0.5 border-2 border-thb27-ink text-[11px] group-hover/r:border-thb27-paper group-focus-visible/r:border-thb27-paper">04</b>FAQ<span class="ml-auto text-lg" aria-hidden="true">→</span></a></div>
</nav>
<div class="flex-1 grid content-start gap-4.5 p-5.5" aria-hidden="true">
<div class="w-max -rotate-1.5 px-4 py-3 border-[3px] border-thb27-ink bg-thb27-acc text-xs font-bold leading-[1.7] tracking-[0.06em] shadow-[6px_6px_0_var(--color-thb27-ink)]">EST. 2026<br>NO COOKIES<br>NO TRACKING</div>
<div class="h-37.5 border-[3px] border-thb27-ink [background:repeating-linear-gradient(-45deg,var(--color-thb27-paper)_0_12px,oklch(0.18_0.01_90/0.12)_12px_24px)]"></div>
</div>
<div class="mt-auto overflow-hidden py-2.25 border-t-[3px] border-thb27-ink bg-thb27-ink text-thb27-paper" aria-hidden="true">
<div class="flex w-max animate-thb27-tape motion-reduce:animate-none">
<span class="whitespace-nowrap text-[11.5px] font-bold tracking-[0.14em]">FREE SHIPPING OVER $80 ★ PRESS THE PLATE ★ EVERYTHING HAS A BORDER ★ </span>
<span class="whitespace-nowrap text-[11.5px] font-bold tracking-[0.14em]">FREE SHIPPING OVER $80 ★ PRESS THE PLATE ★ EVERYTHING HAS A BORDER ★ </span>
</div>
</div>
</div>
</section>@import "tailwindcss";
@theme {
--color-thb27-paper: #f7f4e9;
--color-thb27-paper: oklch(0.96 0.01 95);
--color-thb27-ink: #1f1c14;
--color-thb27-ink: oklch(0.18 0.01 90);
--color-thb27-acc: #f2d43c;
--color-thb27-acc: oklch(0.86 0.17 95);
--color-thb27-acc2: #ffe23f;
--color-thb27-acc2: oklch(0.9 0.19 95);
--font-thb27-mono: 'JetBrains Mono', ui-monospace, 'Cascadia Mono', Menlo, monospace;
--animate-thb27-tape: thb27-tape 14s linear infinite;
}
/* Keyframes are a rule, not a value — the @theme --animate-* entry only names this. */
@keyframes thb27-tape {
to {
translate: -50% 0;
}
}
/* 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-27 {
width: 100%;
min-height: 100svh;
}@import "tailwindcss";
@theme {
--color-thb27-paper: #f7f4e9;
--color-thb27-paper: oklch(0.96 0.01 95);
--color-thb27-ink: #1f1c14;
--color-thb27-ink: oklch(0.18 0.01 90);
--color-thb27-acc: #f2d43c;
--color-thb27-acc: oklch(0.86 0.17 95);
--color-thb27-acc2: #ffe23f;
--color-thb27-acc2: oklch(0.9 0.19 95);
--font-thb27-mono: 'JetBrains Mono', ui-monospace, 'Cascadia Mono', Menlo, monospace;
--animate-thb27-tape: thb27-tape 14s linear infinite;
}
/* Keyframes are a rule, not a value — the @theme --animate-* entry only names this. */
@keyframes thb27-tape {
to {
translate: -50% 0;
}
}
/* 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-27 {
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-thb27-paper: #f7f4e9;
--color-thb27-paper: oklch(0.96 0.01 95);
--color-thb27-ink: #1f1c14;
--color-thb27-ink: oklch(0.18 0.01 90);
--color-thb27-acc: #f2d43c;
--color-thb27-acc: oklch(0.86 0.17 95);
--color-thb27-acc2: #ffe23f;
--color-thb27-acc2: oklch(0.9 0.19 95);
--font-thb27-mono: 'JetBrains Mono', ui-monospace, 'Cascadia Mono', Menlo, monospace;
--animate-thb27-tape: thb27-tape 14s linear infinite;
}
/* Keyframes are a rule, not a value — the @theme --animate-* entry only names this. */
@keyframes thb27-tape {
to {
translate: -50% 0;
}
}
/* 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-27 {
width: 100%;
min-height: 100svh;
}@import "tailwindcss";
@theme {
--color-thb27-paper: #f7f4e9;
--color-thb27-paper: oklch(0.96 0.01 95);
--color-thb27-ink: #1f1c14;
--color-thb27-ink: oklch(0.18 0.01 90);
--color-thb27-acc: #f2d43c;
--color-thb27-acc: oklch(0.86 0.17 95);
--color-thb27-acc2: #ffe23f;
--color-thb27-acc2: oklch(0.9 0.19 95);
--font-thb27-mono: 'JetBrains Mono', ui-monospace, 'Cascadia Mono', Menlo, monospace;
--animate-thb27-tape: thb27-tape 14s linear infinite;
}
/* Keyframes are a rule, not a value — the @theme --animate-* entry only names this. */
@keyframes thb27-tape {
to {
translate: -50% 0;
}
}
/* 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-27 {
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=JetBrains+Mono:wght@400;500;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=JetBrains+Mono:wght@400;500;700;800&display=swap">What changed in the port
Which parts became utilities, which stayed CSS, and why.
- The press is the port's best moment: the 6px travel and the 6px shadow it lands on sit one class list apart (
translate-x-1.5 translate-y-1.5next toshadow-[0_0_0_…]), where the CSS version keeps them in two rules that must be kept equal by hand. :checked ~ header .plateand its six relatives becomegroup-has-checked:utilities, including the MENU/CLOSE word swap as ahidden/blockpair.duration-[60ms] ease-linearis now stated on each element, so the style's thesis (cuts, not curves) is legible in the markup rather than buried in a shared transition rule.- The row inversion uses a named group (
group/r) so the number badge's border can flip in the same cut as the row's background. - The marquee becomes an
--animate-*token plusw-maxandflex; the@keyframesblock is the only motion left in the stylesheet. - The dot grid and the diagonal hatch both stay arbitrary background values — neither is a design-scale value, and both belong on the element that shows them.
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: Brutalist Design Bordered Tailwind Hamburger Menu
Source: https://codefronts.com/navigation/tailwind-hamburger-menus/brutalist-design-bordered-tailwind-hamburger-menu/
Neo-brutalism with its rules intact: 3px black borders on everything, hard offset shadows that do not blur, one shrieking yellow, uppercase mono type — and motion that CUTS instead of eases, because in this dialect a transition curve is a lie. The press is the port's neatest line: the plate travels exactly its shadow's offset and lands flat, which is two utilities sitting next to each other.
## HTML
```html
<section class="thb-27 w-full min-h-svh grid justify-center content-start bg-thb27-paper font-thb27-mono text-thb27-ink px-5 py-9" aria-label="Brutalist bordered menu demo">
<div class="group relative flex flex-col w-[min(400px,88vw)] h-140 overflow-hidden border-[3px] border-thb27-ink bg-thb27-paper shadow-[8px_8px_0_var(--color-thb27-ink)] [background-image:radial-gradient(oklch(0.18_0.01_90/0.14)_1.2px,transparent_1.3px)] [background-size:18px_18px]">
<input type="checkbox" id="thb27-t" class="peer absolute w-px h-px overflow-hidden whitespace-nowrap [clip-path:inset(50%)]">
<header class="relative z-2 flex items-center justify-between p-3.5 border-b-[3px] border-thb27-ink bg-thb27-paper">
<span class="text-base font-bold tracking-[0.04em]">RAW—GOODS<i class="not-italic align-super text-[10px]" aria-hidden="true">®</i></span>
<label for="thb27-t" class="flex items-center gap-2.5 min-h-11.5 px-3.5 border-[3px] border-thb27-ink bg-thb27-acc cursor-pointer select-none shadow-[6px_6px_0_var(--color-thb27-ink)] transition-[translate,box-shadow,background] duration-[60ms] ease-linear hover:bg-thb27-acc2 peer-focus-visible:outline-3 peer-focus-visible:outline-thb27-ink peer-focus-visible:outline-offset-3 group-has-checked:translate-x-1.5 group-has-checked:translate-y-1.5 group-has-checked:shadow-[0_0_0_var(--color-thb27-ink)]">
<span class="relative block w-5 h-3.5" aria-hidden="true">
<i class="absolute left-0 top-0 w-5 h-[3px] bg-thb27-ink transition-[translate,rotate] duration-[60ms] ease-linear group-has-checked:translate-y-[5.5px] group-has-checked:rotate-45"></i>
<i class="absolute left-0 top-[5.5px] w-5 h-[3px] bg-thb27-ink transition-[opacity] duration-[60ms] ease-linear group-has-checked:opacity-0"></i>
<i class="absolute left-0 top-[11px] w-5 h-[3px] bg-thb27-ink transition-[translate,rotate] duration-[60ms] ease-linear group-has-checked:-translate-y-[5.5px] group-has-checked:-rotate-45"></i>
</span>
<span class="text-xs font-bold tracking-[0.08em] group-has-checked:hidden" aria-hidden="true">MENU</span>
<span class="hidden text-xs font-bold tracking-[0.08em] group-has-checked:block" aria-hidden="true">CLOSE</span>
</label>
</header>
<nav aria-label="Site" class="absolute inset-x-0 top-[79px] bottom-10 z-1 hidden flex-col bg-thb27-paper border-b-[3px] border-thb27-ink group-has-checked:flex">
<div class="border-b-[3px] border-thb27-ink"><a href="#shop" class="group/r flex items-center gap-3.5 min-h-16 px-4.5 text-[15px] font-bold tracking-[0.06em] text-thb27-ink no-underline hover:bg-thb27-ink hover:text-thb27-paper focus-visible:bg-thb27-ink focus-visible:text-thb27-paper focus-visible:outline-3 focus-visible:outline-thb27-acc focus-visible:-outline-offset-6"><b class="px-1.5 py-0.5 border-2 border-thb27-ink text-[11px] group-hover/r:border-thb27-paper group-focus-visible/r:border-thb27-paper">01</b>SHOP ALL<span class="ml-auto text-lg" aria-hidden="true">→</span></a></div>
<div class="border-b-[3px] border-thb27-ink"><a href="#drops" class="group/r flex items-center gap-3.5 min-h-16 px-4.5 text-[15px] font-bold tracking-[0.06em] text-thb27-ink no-underline hover:bg-thb27-ink hover:text-thb27-paper focus-visible:bg-thb27-ink focus-visible:text-thb27-paper focus-visible:outline-3 focus-visible:outline-thb27-acc focus-visible:-outline-offset-6"><b class="px-1.5 py-0.5 border-2 border-thb27-ink text-[11px] group-hover/r:border-thb27-paper group-focus-visible/r:border-thb27-paper">02</b>DROPS<span class="ml-auto text-lg" aria-hidden="true">→</span></a></div>
<div class="border-b-[3px] border-thb27-ink"><a href="#manifesto" class="group/r flex items-center gap-3.5 min-h-16 px-4.5 text-[15px] font-bold tracking-[0.06em] text-thb27-ink no-underline hover:bg-thb27-ink hover:text-thb27-paper focus-visible:bg-thb27-ink focus-visible:text-thb27-paper focus-visible:outline-3 focus-visible:outline-thb27-acc focus-visible:-outline-offset-6"><b class="px-1.5 py-0.5 border-2 border-thb27-ink text-[11px] group-hover/r:border-thb27-paper group-focus-visible/r:border-thb27-paper">03</b>MANIFESTO<span class="ml-auto text-lg" aria-hidden="true">→</span></a></div>
<div class="border-b-[3px] border-thb27-ink"><a href="#faq" class="group/r flex items-center gap-3.5 min-h-16 px-4.5 text-[15px] font-bold tracking-[0.06em] text-thb27-ink no-underline hover:bg-thb27-ink hover:text-thb27-paper focus-visible:bg-thb27-ink focus-visible:text-thb27-paper focus-visible:outline-3 focus-visible:outline-thb27-acc focus-visible:-outline-offset-6"><b class="px-1.5 py-0.5 border-2 border-thb27-ink text-[11px] group-hover/r:border-thb27-paper group-focus-visible/r:border-thb27-paper">04</b>FAQ<span class="ml-auto text-lg" aria-hidden="true">→</span></a></div>
</nav>
<div class="flex-1 grid content-start gap-4.5 p-5.5" aria-hidden="true">
<div class="w-max -rotate-1.5 px-4 py-3 border-[3px] border-thb27-ink bg-thb27-acc text-xs font-bold leading-[1.7] tracking-[0.06em] shadow-[6px_6px_0_var(--color-thb27-ink)]">EST. 2026<br>NO COOKIES<br>NO TRACKING</div>
<div class="h-37.5 border-[3px] border-thb27-ink [background:repeating-linear-gradient(-45deg,var(--color-thb27-paper)_0_12px,oklch(0.18_0.01_90/0.12)_12px_24px)]"></div>
</div>
<div class="mt-auto overflow-hidden py-2.25 border-t-[3px] border-thb27-ink bg-thb27-ink text-thb27-paper" aria-hidden="true">
<div class="flex w-max animate-thb27-tape motion-reduce:animate-none">
<span class="whitespace-nowrap text-[11.5px] font-bold tracking-[0.14em]">FREE SHIPPING OVER $80 ★ PRESS THE PLATE ★ EVERYTHING HAS A BORDER ★ </span>
<span class="whitespace-nowrap text-[11.5px] font-bold tracking-[0.14em]">FREE SHIPPING OVER $80 ★ PRESS THE PLATE ★ EVERYTHING HAS A BORDER ★ </span>
</div>
</div>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-thb27-paper: #f7f4e9;
--color-thb27-paper: oklch(0.96 0.01 95);
--color-thb27-ink: #1f1c14;
--color-thb27-ink: oklch(0.18 0.01 90);
--color-thb27-acc: #f2d43c;
--color-thb27-acc: oklch(0.86 0.17 95);
--color-thb27-acc2: #ffe23f;
--color-thb27-acc2: oklch(0.9 0.19 95);
--font-thb27-mono: 'JetBrains Mono', ui-monospace, 'Cascadia Mono', Menlo, monospace;
--animate-thb27-tape: thb27-tape 14s linear infinite;
}
/* Keyframes are a rule, not a value — the @theme --animate-* entry only names this. */
@keyframes thb27-tape {
to {
translate: -50% 0;
}
}
/* 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-27 {
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: Brutalist Design Bordered Tailwind Hamburger Menu
Source: https://codefronts.com/navigation/tailwind-hamburger-menus/brutalist-design-bordered-tailwind-hamburger-menu/
Neo-brutalism with its rules intact: 3px black borders on everything, hard offset shadows that do not blur, one shrieking yellow, uppercase mono type — and motion that CUTS instead of eases, because in this dialect a transition curve is a lie. The press is the port's neatest line: the plate travels exactly its shadow's offset and lands flat, which is two utilities sitting next to each other.
## HTML
```html
<section class="thb-27 w-full min-h-svh grid justify-center content-start bg-thb27-paper font-thb27-mono text-thb27-ink px-5 py-9" aria-label="Brutalist bordered menu demo">
<div class="group relative flex flex-col w-[min(400px,88vw)] h-140 overflow-hidden border-[3px] border-thb27-ink bg-thb27-paper shadow-[8px_8px_0_var(--color-thb27-ink)] [background-image:radial-gradient(oklch(0.18_0.01_90/0.14)_1.2px,transparent_1.3px)] [background-size:18px_18px]">
<input type="checkbox" id="thb27-t" class="peer absolute w-px h-px overflow-hidden whitespace-nowrap [clip-path:inset(50%)]">
<header class="relative z-2 flex items-center justify-between p-3.5 border-b-[3px] border-thb27-ink bg-thb27-paper">
<span class="text-base font-bold tracking-[0.04em]">RAW—GOODS<i class="not-italic align-super text-[10px]" aria-hidden="true">®</i></span>
<label for="thb27-t" class="flex items-center gap-2.5 min-h-11.5 px-3.5 border-[3px] border-thb27-ink bg-thb27-acc cursor-pointer select-none shadow-[6px_6px_0_var(--color-thb27-ink)] transition-[translate,box-shadow,background] duration-[60ms] ease-linear hover:bg-thb27-acc2 peer-focus-visible:outline-3 peer-focus-visible:outline-thb27-ink peer-focus-visible:outline-offset-3 group-has-checked:translate-x-1.5 group-has-checked:translate-y-1.5 group-has-checked:shadow-[0_0_0_var(--color-thb27-ink)]">
<span class="relative block w-5 h-3.5" aria-hidden="true">
<i class="absolute left-0 top-0 w-5 h-[3px] bg-thb27-ink transition-[translate,rotate] duration-[60ms] ease-linear group-has-checked:translate-y-[5.5px] group-has-checked:rotate-45"></i>
<i class="absolute left-0 top-[5.5px] w-5 h-[3px] bg-thb27-ink transition-[opacity] duration-[60ms] ease-linear group-has-checked:opacity-0"></i>
<i class="absolute left-0 top-[11px] w-5 h-[3px] bg-thb27-ink transition-[translate,rotate] duration-[60ms] ease-linear group-has-checked:-translate-y-[5.5px] group-has-checked:-rotate-45"></i>
</span>
<span class="text-xs font-bold tracking-[0.08em] group-has-checked:hidden" aria-hidden="true">MENU</span>
<span class="hidden text-xs font-bold tracking-[0.08em] group-has-checked:block" aria-hidden="true">CLOSE</span>
</label>
</header>
<nav aria-label="Site" class="absolute inset-x-0 top-[79px] bottom-10 z-1 hidden flex-col bg-thb27-paper border-b-[3px] border-thb27-ink group-has-checked:flex">
<div class="border-b-[3px] border-thb27-ink"><a href="#shop" class="group/r flex items-center gap-3.5 min-h-16 px-4.5 text-[15px] font-bold tracking-[0.06em] text-thb27-ink no-underline hover:bg-thb27-ink hover:text-thb27-paper focus-visible:bg-thb27-ink focus-visible:text-thb27-paper focus-visible:outline-3 focus-visible:outline-thb27-acc focus-visible:-outline-offset-6"><b class="px-1.5 py-0.5 border-2 border-thb27-ink text-[11px] group-hover/r:border-thb27-paper group-focus-visible/r:border-thb27-paper">01</b>SHOP ALL<span class="ml-auto text-lg" aria-hidden="true">→</span></a></div>
<div class="border-b-[3px] border-thb27-ink"><a href="#drops" class="group/r flex items-center gap-3.5 min-h-16 px-4.5 text-[15px] font-bold tracking-[0.06em] text-thb27-ink no-underline hover:bg-thb27-ink hover:text-thb27-paper focus-visible:bg-thb27-ink focus-visible:text-thb27-paper focus-visible:outline-3 focus-visible:outline-thb27-acc focus-visible:-outline-offset-6"><b class="px-1.5 py-0.5 border-2 border-thb27-ink text-[11px] group-hover/r:border-thb27-paper group-focus-visible/r:border-thb27-paper">02</b>DROPS<span class="ml-auto text-lg" aria-hidden="true">→</span></a></div>
<div class="border-b-[3px] border-thb27-ink"><a href="#manifesto" class="group/r flex items-center gap-3.5 min-h-16 px-4.5 text-[15px] font-bold tracking-[0.06em] text-thb27-ink no-underline hover:bg-thb27-ink hover:text-thb27-paper focus-visible:bg-thb27-ink focus-visible:text-thb27-paper focus-visible:outline-3 focus-visible:outline-thb27-acc focus-visible:-outline-offset-6"><b class="px-1.5 py-0.5 border-2 border-thb27-ink text-[11px] group-hover/r:border-thb27-paper group-focus-visible/r:border-thb27-paper">03</b>MANIFESTO<span class="ml-auto text-lg" aria-hidden="true">→</span></a></div>
<div class="border-b-[3px] border-thb27-ink"><a href="#faq" class="group/r flex items-center gap-3.5 min-h-16 px-4.5 text-[15px] font-bold tracking-[0.06em] text-thb27-ink no-underline hover:bg-thb27-ink hover:text-thb27-paper focus-visible:bg-thb27-ink focus-visible:text-thb27-paper focus-visible:outline-3 focus-visible:outline-thb27-acc focus-visible:-outline-offset-6"><b class="px-1.5 py-0.5 border-2 border-thb27-ink text-[11px] group-hover/r:border-thb27-paper group-focus-visible/r:border-thb27-paper">04</b>FAQ<span class="ml-auto text-lg" aria-hidden="true">→</span></a></div>
</nav>
<div class="flex-1 grid content-start gap-4.5 p-5.5" aria-hidden="true">
<div class="w-max -rotate-1.5 px-4 py-3 border-[3px] border-thb27-ink bg-thb27-acc text-xs font-bold leading-[1.7] tracking-[0.06em] shadow-[6px_6px_0_var(--color-thb27-ink)]">EST. 2026<br>NO COOKIES<br>NO TRACKING</div>
<div class="h-37.5 border-[3px] border-thb27-ink [background:repeating-linear-gradient(-45deg,var(--color-thb27-paper)_0_12px,oklch(0.18_0.01_90/0.12)_12px_24px)]"></div>
</div>
<div class="mt-auto overflow-hidden py-2.25 border-t-[3px] border-thb27-ink bg-thb27-ink text-thb27-paper" aria-hidden="true">
<div class="flex w-max animate-thb27-tape motion-reduce:animate-none">
<span class="whitespace-nowrap text-[11.5px] font-bold tracking-[0.14em]">FREE SHIPPING OVER $80 ★ PRESS THE PLATE ★ EVERYTHING HAS A BORDER ★ </span>
<span class="whitespace-nowrap text-[11.5px] font-bold tracking-[0.14em]">FREE SHIPPING OVER $80 ★ PRESS THE PLATE ★ EVERYTHING HAS A BORDER ★ </span>
</div>
</div>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-thb27-paper: #f7f4e9;
--color-thb27-paper: oklch(0.96 0.01 95);
--color-thb27-ink: #1f1c14;
--color-thb27-ink: oklch(0.18 0.01 90);
--color-thb27-acc: #f2d43c;
--color-thb27-acc: oklch(0.86 0.17 95);
--color-thb27-acc2: #ffe23f;
--color-thb27-acc2: oklch(0.9 0.19 95);
--font-thb27-mono: 'JetBrains Mono', ui-monospace, 'Cascadia Mono', Menlo, monospace;
--animate-thb27-tape: thb27-tape 14s linear infinite;
}
/* Keyframes are a rule, not a value — the @theme --animate-* entry only names this. */
@keyframes thb27-tape {
to {
translate: -50% 0;
}
}
/* 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-27 {
width: 100%;
min-height: 100svh;
}
```How this works
Brutalist depth is the shadow that admits it is fake: zero blur, pure offset, and interaction means physically closing the gap.
<label class="border-[3px] border-thb27-ink bg-thb27-acc
shadow-[6px_6px_0_var(--color-thb27-ink)]
transition-[translate,box-shadow] duration-[60ms] ease-linear
group-has-checked:translate-x-1.5 group-has-checked:translate-y-1.5
group-has-checked:shadow-[0_0_0_var(--color-thb27-ink)]">The element travels exactly its shadow's offset and lands flat on the surface. In a stylesheet the 6px in the shadow and the 6px in the translate live in two rules; here they are one class list apart, which is the difference between a fragile trick and an obvious one.
Inversion, not tinting. Rows flip completely on hover and focus — no 8%-alpha wash — and the number badge swaps its border colour in the same 60ms cut through a named group.
The ticker is kitsch on any other site and native vocabulary here: two identical copies of the text in a w-max flex track, translated -50% by one keyframe. Both copies must match exactly or the loop jumps.
The engine is demo 05's, verbatim: a clipped, still-focusable checkbox read through group-has-checked:. The style is loud; the accessibility is not optional. The focus ring sits 3px outside the shadow zone so it never disappears against a black border.
Make it yours
- The palette is paper, ink and ONE accent. Swap
--color-thb27-accfor hot pink or acid green; never add a fourth colour, the tension IS the restraint. - Border weight and shadow offset are a token pair (3px / 6px). Scale to 4px/8px for poster weight, and keep offset at roughly 2× border or the physics reads wrong.
- Rotate at most two elements ±1.5°. More and it becomes a parody of itself.
- The marquee text is one string repeated twice in the markup — edit both copies together.
- Speed: the
14sin the--animate-thb27-tapetoken. Under 8s it reads as panic.
Gotchas — read before shipping
- Hard shadows must be
shadow-[…_0_…]with zero blur, neverdrop-shadow-*— a filter antialiases the edge soft, and crisp is the whole brand. - The press moves the element 6px. Keep 6px of breathing room in the layout, and do not attach anything that must stay put mid-press.
- Uppercase mono tanks readability below about 13px. The rows here are 15px, and body copy on a brutalist site still stays sentence-case.
- Black on yellow is 13:1 and fine, but a black focus ring vanishes against black borders — offset it OUTSIDE the shadow zone, as here.
duration-[60ms]is deliberate, not a mistake. Do not “fix” it to 200ms with an ease curve; that reverses the style's entire thesis.motion-reduce:still applies: 60ms cuts are already calm, but the marquee must stop dead.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
Borders, hard shadows, checkbox state and keyframe marquees are 2012-era CSS; :has() behind has-checked: needs Firefox 121. Ironically the most avant-garde-looking demo is the most backwards-compatible.