06 / 17
All 17 in 17 Tailwind CSS Dashboard Layouts
- 01Tailwind CSS Bento Grid Dashboard Layout
- 02Tailwind CSS Collapsible Sidebar Admin Dashboard
- 03Tailwind CSS Dashboard KPI Stat Cards Grid
- 04Tailwind CSS Master-Detail Split View Inbox Layout
- 05Tailwind CSS Fixed Header Dashboard with Independent Scroll Panels
- 06Tailwind CSS Grid Template Areas Dashboard Layout
- 07Tailwind CSS Responsive Off-Canvas Sidebar Drawer Dashboard
- 08Tailwind CSS Container Query Responsive Dashboard Cards
- 09Tailwind CSS E-commerce Admin Dashboard with Bulk Actions
- 10Tailwind CSS Dark Mode Dashboard with Light / Dark / System Toggle
- 11Tailwind CSS Multi-Level Nested Sidebar Navigation Layout
- 12Minimal Tailwind CSS Admin Dashboard Template (No JavaScript)
- 13Tailwind CSS AI Copilot Chat Sidebar Dashboard Layout
- 14Tailwind CSS Data Table with Sticky Header and Sticky First Column
- 15Tailwind CSS Masonry Grid Dashboard Layout (Columns vs Grid Dense)
- 16Tailwind CSS Full-Screen Analytics Dashboard (100vh, No Scroll)
- 17Tailwind CSS Top Navigation Bar Dashboard Layout with Tabs
Tailwind CSS Grid Template Areas Dashboard Layout
Tailwind has no grid-areas utility — and this demo shows you do not need one. The whole header / sidebar / main / aside / footer shell is an arbitrary property, [grid-template-areas:'header_header_header'_'sidebar_main_aside'_'footer_footer_footer'], re-drawn under @max-[41rem]/stage:. Drag the stage edge and a live badge reports which template is active.
Mosaic by Cruip: a complete Tailwind admin dashboard template in HTML, React, Next.js and Vue · $69
Cruip · Mosaic by Cruip · Affiliate link
The code
<section class="tdl-06 grid w-full min-h-svh place-items-center bg-tdl06-bg p-3 font-tdl06-sans text-tdl06-ink antialiased sm:p-5" aria-label="grid-template-areas dashboard demo">
<div class="@container/stage h-[calc(100svh-2.5rem)] min-h-[32rem] w-full max-w-full min-w-[20rem] resize-x overflow-auto rounded-2xl border border-tdl06-edge bg-tdl06-paper bg-[radial-gradient(var(--color-tdl06-dot)_1px,transparent_1px)] bg-size-[16px_16px] p-3.5">
<div class="grid h-full grid-cols-[12.5rem_minmax(0,1fr)_14.5rem] grid-rows-[3.375rem_minmax(0,1fr)_2.75rem] gap-3 [grid-template-areas:'header_header_header'_'sidebar_main_aside'_'footer_footer_footer'] @max-[41rem]/stage:grid-cols-[4rem_minmax(0,1fr)] @max-[41rem]/stage:grid-rows-[3.375rem_minmax(0,1fr)_auto_2.75rem] @max-[41rem]/stage:[grid-template-areas:'header_header'_'sidebar_main'_'aside_aside'_'footer_footer'] *:relative *:min-w-0 *:rounded-xl *:border-[1.5px] *:border-dashed *:border-tdl06-line/55 *:bg-linear-150 *:from-tdl06-fill2 *:to-tdl06-fill *:px-3.5 *:py-3 *:transition-colors *:hover:border-tdl06-acc *:hover:bg-tdl06-hover [&>*>b]:absolute [&>*>b]:-top-px [&>*>b]:-left-px [&>*>b]:rounded-[10px_0_10px_0] [&>*>b]:bg-tdl06-line [&>*>b]:px-2.5 [&>*>b]:py-1 [&>*>b]:font-tdl06-mono [&>*>b]:text-[10px] [&>*>b]:font-bold [&>*>b]:tracking-[0.06em] [&>*>b]:text-white [&>*:hover>b]:bg-tdl06-acc">
<header class="flex items-center gap-3.5 pl-24! [grid-area:header]"><b>header</b><span class="truncate font-tdl06-mono text-[11px] font-semibold text-tdl06-mut">[grid-area:header]</span>
<span class="ml-auto flex flex-none items-center gap-1.5 rounded-full bg-tdl06-acc/10 px-2.5 py-1 text-[10.5px] font-bold tracking-[0.06em] text-tdl06-acc uppercase"><i aria-hidden="true" class="size-1.5 rounded-full bg-tdl06-acc"></i><span class="@max-[41rem]/stage:hidden">3-column template</span><span class="hidden @max-[41rem]/stage:inline">2-column template</span></span>
</header>
<nav aria-label="Demo sidebar" class="flex flex-col gap-1.25 pt-8.5! [grid-area:sidebar] @max-[41rem]/stage:px-2! [&>a]:flex [&>a]:h-10 [&>a]:items-center [&>a]:gap-2.5 [&>a]:rounded-lg [&>a]:px-2.5 [&>a]:text-[12.5px] [&>a]:font-semibold [&>a]:whitespace-nowrap [&>a]:text-tdl06-mut [&>a]:no-underline [&>a]:transition-colors [&>a:hover]:bg-tdl06-acc/8 [&>a:hover]:text-tdl06-ink [&>a:focus-visible]:outline-2 [&>a:focus-visible]:-outline-offset-2 [&>a:focus-visible]:outline-tdl06-acc [&>a[aria-current=page]]:bg-tdl06-acc/12 [&>a[aria-current=page]]:text-tdl06-acc @max-[41rem]/stage:[&>a]:justify-center @max-[41rem]/stage:[&>a]:px-0 [&_i]:size-4 [&_i]:flex-none [&_i]:rounded-[5px] [&_i]:bg-tdl06-line/45 [&>a[aria-current=page]_i]:bg-tdl06-acc"><b>sidebar</b>
<a href="#dash" aria-current="page"><i aria-hidden="true"></i><span class="@max-[41rem]/stage:sr-only">Dashboard</span></a>
<a href="#reports"><i aria-hidden="true"></i><span class="@max-[41rem]/stage:sr-only">Reports</span></a>
<a href="#team"><i aria-hidden="true"></i><span class="@max-[41rem]/stage:sr-only">Team</span></a>
<a href="#settings"><i aria-hidden="true"></i><span class="@max-[41rem]/stage:sr-only">Settings</span></a>
</nav>
<main class="pt-9! [grid-area:main]"><b>main</b>
<div aria-hidden="true" class="grid gap-3 *:block *:h-3.75 *:w-(--w) *:rounded-full *:bg-tdl06-line/25"><span style="--w:72%"></span><span style="--w:94%"></span><span style="--w:58%"></span><span style="--w:86%"></span><span style="--w:66%"></span></div>
<div aria-hidden="true" class="mt-5 grid grid-cols-3 gap-3 *:h-16 *:rounded-lg *:border *:border-tdl06-line/25 *:bg-white/70"><span></span><span></span><span></span></div>
</main>
<aside class="flex flex-col gap-3.5 pt-9! [grid-area:aside] @max-[41rem]/stage:flex-row @max-[41rem]/stage:pt-8!"><b>aside</b>
<p class="grid gap-1.75 text-xs font-semibold text-tdl06-mut @max-[41rem]/stage:flex-1">Quota · 64%<span class="h-2 overflow-hidden rounded-full bg-tdl06-line/22"><i class="block h-full w-[64%] rounded-full bg-linear-to-r from-tdl06-acc to-tdl06-line"></i></span></p>
<p class="grid gap-1.75 text-xs font-semibold text-tdl06-mut @max-[41rem]/stage:flex-1">Storage · 38%<span class="h-2 overflow-hidden rounded-full bg-tdl06-line/22"><i class="block h-full w-[38%] rounded-full bg-linear-to-r from-tdl06-acc to-tdl06-line"></i></span></p>
</aside>
<footer class="flex items-center gap-3 overflow-hidden pl-22! [grid-area:footer]"><b>footer</b>
<code class="truncate font-tdl06-mono text-[10.5px] font-semibold text-tdl06-mut @max-[41rem]/stage:hidden">'header header header' 'sidebar main aside' 'footer footer footer'</code>
<code class="hidden truncate font-tdl06-mono text-[10.5px] font-semibold text-tdl06-mut @max-[41rem]/stage:block">'header header' 'sidebar main' 'aside aside' 'footer footer'</code>
</footer>
</div>
</div>
<p class="mt-2 flex items-center gap-2 text-xs font-semibold text-tdl06-mut"><span aria-hidden="true" class="font-tdl06-mono text-tdl06-acc">⤡</span>Drag the stage's bottom-right corner to cross the 41rem breakpoint</p>
</section><section class="tdl-06 grid w-full min-h-svh place-items-center bg-tdl06-bg p-3 font-tdl06-sans text-tdl06-ink antialiased sm:p-5" aria-label="grid-template-areas dashboard demo">
<div class="@container/stage h-[calc(100svh-2.5rem)] min-h-[32rem] w-full max-w-full min-w-[20rem] resize-x overflow-auto rounded-2xl border border-tdl06-edge bg-tdl06-paper bg-[radial-gradient(var(--color-tdl06-dot)_1px,transparent_1px)] bg-size-[16px_16px] p-3.5">
<div class="grid h-full grid-cols-[12.5rem_minmax(0,1fr)_14.5rem] grid-rows-[3.375rem_minmax(0,1fr)_2.75rem] gap-3 [grid-template-areas:'header_header_header'_'sidebar_main_aside'_'footer_footer_footer'] @max-[41rem]/stage:grid-cols-[4rem_minmax(0,1fr)] @max-[41rem]/stage:grid-rows-[3.375rem_minmax(0,1fr)_auto_2.75rem] @max-[41rem]/stage:[grid-template-areas:'header_header'_'sidebar_main'_'aside_aside'_'footer_footer'] *:relative *:min-w-0 *:rounded-xl *:border-[1.5px] *:border-dashed *:border-tdl06-line/55 *:bg-linear-150 *:from-tdl06-fill2 *:to-tdl06-fill *:px-3.5 *:py-3 *:transition-colors *:hover:border-tdl06-acc *:hover:bg-tdl06-hover [&>*>b]:absolute [&>*>b]:-top-px [&>*>b]:-left-px [&>*>b]:rounded-[10px_0_10px_0] [&>*>b]:bg-tdl06-line [&>*>b]:px-2.5 [&>*>b]:py-1 [&>*>b]:font-tdl06-mono [&>*>b]:text-[10px] [&>*>b]:font-bold [&>*>b]:tracking-[0.06em] [&>*>b]:text-white [&>*:hover>b]:bg-tdl06-acc">
<header class="flex items-center gap-3.5 pl-24! [grid-area:header]"><b>header</b><span class="truncate font-tdl06-mono text-[11px] font-semibold text-tdl06-mut">[grid-area:header]</span>
<span class="ml-auto flex flex-none items-center gap-1.5 rounded-full bg-tdl06-acc/10 px-2.5 py-1 text-[10.5px] font-bold tracking-[0.06em] text-tdl06-acc uppercase"><i aria-hidden="true" class="size-1.5 rounded-full bg-tdl06-acc"></i><span class="@max-[41rem]/stage:hidden">3-column template</span><span class="hidden @max-[41rem]/stage:inline">2-column template</span></span>
</header>
<nav aria-label="Demo sidebar" class="flex flex-col gap-1.25 pt-8.5! [grid-area:sidebar] @max-[41rem]/stage:px-2! [&>a]:flex [&>a]:h-10 [&>a]:items-center [&>a]:gap-2.5 [&>a]:rounded-lg [&>a]:px-2.5 [&>a]:text-[12.5px] [&>a]:font-semibold [&>a]:whitespace-nowrap [&>a]:text-tdl06-mut [&>a]:no-underline [&>a]:transition-colors [&>a:hover]:bg-tdl06-acc/8 [&>a:hover]:text-tdl06-ink [&>a:focus-visible]:outline-2 [&>a:focus-visible]:-outline-offset-2 [&>a:focus-visible]:outline-tdl06-acc [&>a[aria-current=page]]:bg-tdl06-acc/12 [&>a[aria-current=page]]:text-tdl06-acc @max-[41rem]/stage:[&>a]:justify-center @max-[41rem]/stage:[&>a]:px-0 [&_i]:size-4 [&_i]:flex-none [&_i]:rounded-[5px] [&_i]:bg-tdl06-line/45 [&>a[aria-current=page]_i]:bg-tdl06-acc"><b>sidebar</b>
<a href="#dash" aria-current="page"><i aria-hidden="true"></i><span class="@max-[41rem]/stage:sr-only">Dashboard</span></a>
<a href="#reports"><i aria-hidden="true"></i><span class="@max-[41rem]/stage:sr-only">Reports</span></a>
<a href="#team"><i aria-hidden="true"></i><span class="@max-[41rem]/stage:sr-only">Team</span></a>
<a href="#settings"><i aria-hidden="true"></i><span class="@max-[41rem]/stage:sr-only">Settings</span></a>
</nav>
<main class="pt-9! [grid-area:main]"><b>main</b>
<div aria-hidden="true" class="grid gap-3 *:block *:h-3.75 *:w-(--w) *:rounded-full *:bg-tdl06-line/25"><span style="--w:72%"></span><span style="--w:94%"></span><span style="--w:58%"></span><span style="--w:86%"></span><span style="--w:66%"></span></div>
<div aria-hidden="true" class="mt-5 grid grid-cols-3 gap-3 *:h-16 *:rounded-lg *:border *:border-tdl06-line/25 *:bg-white/70"><span></span><span></span><span></span></div>
</main>
<aside class="flex flex-col gap-3.5 pt-9! [grid-area:aside] @max-[41rem]/stage:flex-row @max-[41rem]/stage:pt-8!"><b>aside</b>
<p class="grid gap-1.75 text-xs font-semibold text-tdl06-mut @max-[41rem]/stage:flex-1">Quota · 64%<span class="h-2 overflow-hidden rounded-full bg-tdl06-line/22"><i class="block h-full w-[64%] rounded-full bg-linear-to-r from-tdl06-acc to-tdl06-line"></i></span></p>
<p class="grid gap-1.75 text-xs font-semibold text-tdl06-mut @max-[41rem]/stage:flex-1">Storage · 38%<span class="h-2 overflow-hidden rounded-full bg-tdl06-line/22"><i class="block h-full w-[38%] rounded-full bg-linear-to-r from-tdl06-acc to-tdl06-line"></i></span></p>
</aside>
<footer class="flex items-center gap-3 overflow-hidden pl-22! [grid-area:footer]"><b>footer</b>
<code class="truncate font-tdl06-mono text-[10.5px] font-semibold text-tdl06-mut @max-[41rem]/stage:hidden">'header header header' 'sidebar main aside' 'footer footer footer'</code>
<code class="hidden truncate font-tdl06-mono text-[10.5px] font-semibold text-tdl06-mut @max-[41rem]/stage:block">'header header' 'sidebar main' 'aside aside' 'footer footer'</code>
</footer>
</div>
</div>
<p class="mt-2 flex items-center gap-2 text-xs font-semibold text-tdl06-mut"><span aria-hidden="true" class="font-tdl06-mono text-tdl06-acc">⤡</span>Drag the stage's bottom-right corner to cross the 41rem breakpoint</p>
</section>@import "tailwindcss";
@theme {
--color-tdl06-bg: #eef2f7;
--color-tdl06-bg: oklch(0.96 0.01 245);
--color-tdl06-paper: #f8fafc;
--color-tdl06-paper: oklch(0.982 0.005 245);
--color-tdl06-dot: #dbe3ee;
--color-tdl06-dot: oklch(0.91 0.015 250);
--color-tdl06-edge: #d8dfe9;
--color-tdl06-edge: oklch(0.9 0.015 250);
--color-tdl06-ink: #2b3445;
--color-tdl06-ink: oklch(0.3 0.03 255);
--color-tdl06-mut: #556079;
--color-tdl06-mut: oklch(0.48 0.04 260);
--color-tdl06-line: #4f7cc6;
--color-tdl06-line: oklch(0.58 0.12 258);
--color-tdl06-fill: #e9f0fb;
--color-tdl06-fill: oklch(0.95 0.02 255);
--color-tdl06-fill2: #f5f8fd;
--color-tdl06-fill2: oklch(0.977 0.01 255);
--color-tdl06-hover: #eef3fd;
--color-tdl06-hover: oklch(0.965 0.018 260);
--color-tdl06-acc: #2c5fd6;
--color-tdl06-acc: oklch(0.53 0.18 262);
--font-tdl06-sans: 'Space Grotesk', system-ui, sans-serif;
--font-tdl06-mono: 'JetBrains Mono', ui-monospace, monospace;
}
.tdl-06 {
width: 100%;
min-height: 100svh;
}
@media (prefers-reduced-motion: reduce) {
.tdl-06 * {
transition: none !important;
}
}@import "tailwindcss";
@theme {
--color-tdl06-bg: #eef2f7;
--color-tdl06-bg: oklch(0.96 0.01 245);
--color-tdl06-paper: #f8fafc;
--color-tdl06-paper: oklch(0.982 0.005 245);
--color-tdl06-dot: #dbe3ee;
--color-tdl06-dot: oklch(0.91 0.015 250);
--color-tdl06-edge: #d8dfe9;
--color-tdl06-edge: oklch(0.9 0.015 250);
--color-tdl06-ink: #2b3445;
--color-tdl06-ink: oklch(0.3 0.03 255);
--color-tdl06-mut: #556079;
--color-tdl06-mut: oklch(0.48 0.04 260);
--color-tdl06-line: #4f7cc6;
--color-tdl06-line: oklch(0.58 0.12 258);
--color-tdl06-fill: #e9f0fb;
--color-tdl06-fill: oklch(0.95 0.02 255);
--color-tdl06-fill2: #f5f8fd;
--color-tdl06-fill2: oklch(0.977 0.01 255);
--color-tdl06-hover: #eef3fd;
--color-tdl06-hover: oklch(0.965 0.018 260);
--color-tdl06-acc: #2c5fd6;
--color-tdl06-acc: oklch(0.53 0.18 262);
--font-tdl06-sans: 'Space Grotesk', system-ui, sans-serif;
--font-tdl06-mono: 'JetBrains Mono', ui-monospace, monospace;
}
.tdl-06 {
width: 100%;
min-height: 100svh;
}
@media (prefers-reduced-motion: reduce) {
.tdl-06 * {
transition: none !important;
}
}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-tdl06-bg: #eef2f7;
--color-tdl06-bg: oklch(0.96 0.01 245);
--color-tdl06-paper: #f8fafc;
--color-tdl06-paper: oklch(0.982 0.005 245);
--color-tdl06-dot: #dbe3ee;
--color-tdl06-dot: oklch(0.91 0.015 250);
--color-tdl06-edge: #d8dfe9;
--color-tdl06-edge: oklch(0.9 0.015 250);
--color-tdl06-ink: #2b3445;
--color-tdl06-ink: oklch(0.3 0.03 255);
--color-tdl06-mut: #556079;
--color-tdl06-mut: oklch(0.48 0.04 260);
--color-tdl06-line: #4f7cc6;
--color-tdl06-line: oklch(0.58 0.12 258);
--color-tdl06-fill: #e9f0fb;
--color-tdl06-fill: oklch(0.95 0.02 255);
--color-tdl06-fill2: #f5f8fd;
--color-tdl06-fill2: oklch(0.977 0.01 255);
--color-tdl06-hover: #eef3fd;
--color-tdl06-hover: oklch(0.965 0.018 260);
--color-tdl06-acc: #2c5fd6;
--color-tdl06-acc: oklch(0.53 0.18 262);
--font-tdl06-sans: 'Space Grotesk', system-ui, sans-serif;
--font-tdl06-mono: 'JetBrains Mono', ui-monospace, monospace;
}
.tdl-06 {
width: 100%;
min-height: 100svh;
}
@media (prefers-reduced-motion: reduce) {
.tdl-06 * {
transition: none !important;
}
}@import "tailwindcss";
@theme {
--color-tdl06-bg: #eef2f7;
--color-tdl06-bg: oklch(0.96 0.01 245);
--color-tdl06-paper: #f8fafc;
--color-tdl06-paper: oklch(0.982 0.005 245);
--color-tdl06-dot: #dbe3ee;
--color-tdl06-dot: oklch(0.91 0.015 250);
--color-tdl06-edge: #d8dfe9;
--color-tdl06-edge: oklch(0.9 0.015 250);
--color-tdl06-ink: #2b3445;
--color-tdl06-ink: oklch(0.3 0.03 255);
--color-tdl06-mut: #556079;
--color-tdl06-mut: oklch(0.48 0.04 260);
--color-tdl06-line: #4f7cc6;
--color-tdl06-line: oklch(0.58 0.12 258);
--color-tdl06-fill: #e9f0fb;
--color-tdl06-fill: oklch(0.95 0.02 255);
--color-tdl06-fill2: #f5f8fd;
--color-tdl06-fill2: oklch(0.977 0.01 255);
--color-tdl06-hover: #eef3fd;
--color-tdl06-hover: oklch(0.965 0.018 260);
--color-tdl06-acc: #2c5fd6;
--color-tdl06-acc: oklch(0.53 0.18 262);
--font-tdl06-sans: 'Space Grotesk', system-ui, sans-serif;
--font-tdl06-mono: 'JetBrains Mono', ui-monospace, monospace;
}
.tdl-06 {
width: 100%;
min-height: 100svh;
}
@media (prefers-reduced-motion: reduce) {
.tdl-06 * {
transition: none !important;
}
}<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..700&family=JetBrains+Mono:wght@400;500;600;700&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..700&family=JetBrains+Mono:wght@400;500;600;700&display=swap">What changed in the port
Which parts became utilities, which stayed CSS, and why.
grid-template-areasand the fivegrid-arearules became arbitrary properties — Tailwind's answer for any CSS property without a utility.- The shared region styling (dashed border, gradient, hover) sits once on the grid as
*:child variants; the corner tags use[&>*>b]:. - Bug fix: the CSS original sized the inner shell
height:100vhinside a padded100vhstage, so the footer was always cut off. The shell is nowh-full. - UI upgrade: a live badge in the header names the active template; the rail keeps its labels as
sr-only(wasdisplay:none, which removed the link names); the resize hint moved out of the header into a caption under the stage; corner tags no longer overlap header text.
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 CSS Grid Template Areas Dashboard Layout
Source: https://codefronts.com/layouts/tailwind-css-dashboard-layouts/tailwind-css-grid-template-areas-dashboard-layout/
Tailwind has no grid-areas utility — and this demo shows you do not need one. The whole header / sidebar / main / aside / footer shell is an arbitrary property, [grid-template-areas:'header_header_header'_'sidebar_main_aside'_'footer_footer_footer'], re-drawn under @max-[41rem]/stage:. Drag the stage edge and a live badge reports which template is active.
## HTML
```html
<section class="tdl-06 grid w-full min-h-svh place-items-center bg-tdl06-bg p-3 font-tdl06-sans text-tdl06-ink antialiased sm:p-5" aria-label="grid-template-areas dashboard demo">
<div class="@container/stage h-[calc(100svh-2.5rem)] min-h-[32rem] w-full max-w-full min-w-[20rem] resize-x overflow-auto rounded-2xl border border-tdl06-edge bg-tdl06-paper bg-[radial-gradient(var(--color-tdl06-dot)_1px,transparent_1px)] bg-size-[16px_16px] p-3.5">
<div class="grid h-full grid-cols-[12.5rem_minmax(0,1fr)_14.5rem] grid-rows-[3.375rem_minmax(0,1fr)_2.75rem] gap-3 [grid-template-areas:'header_header_header'_'sidebar_main_aside'_'footer_footer_footer'] @max-[41rem]/stage:grid-cols-[4rem_minmax(0,1fr)] @max-[41rem]/stage:grid-rows-[3.375rem_minmax(0,1fr)_auto_2.75rem] @max-[41rem]/stage:[grid-template-areas:'header_header'_'sidebar_main'_'aside_aside'_'footer_footer'] *:relative *:min-w-0 *:rounded-xl *:border-[1.5px] *:border-dashed *:border-tdl06-line/55 *:bg-linear-150 *:from-tdl06-fill2 *:to-tdl06-fill *:px-3.5 *:py-3 *:transition-colors *:hover:border-tdl06-acc *:hover:bg-tdl06-hover [&>*>b]:absolute [&>*>b]:-top-px [&>*>b]:-left-px [&>*>b]:rounded-[10px_0_10px_0] [&>*>b]:bg-tdl06-line [&>*>b]:px-2.5 [&>*>b]:py-1 [&>*>b]:font-tdl06-mono [&>*>b]:text-[10px] [&>*>b]:font-bold [&>*>b]:tracking-[0.06em] [&>*>b]:text-white [&>*:hover>b]:bg-tdl06-acc">
<header class="flex items-center gap-3.5 pl-24! [grid-area:header]"><b>header</b><span class="truncate font-tdl06-mono text-[11px] font-semibold text-tdl06-mut">[grid-area:header]</span>
<span class="ml-auto flex flex-none items-center gap-1.5 rounded-full bg-tdl06-acc/10 px-2.5 py-1 text-[10.5px] font-bold tracking-[0.06em] text-tdl06-acc uppercase"><i aria-hidden="true" class="size-1.5 rounded-full bg-tdl06-acc"></i><span class="@max-[41rem]/stage:hidden">3-column template</span><span class="hidden @max-[41rem]/stage:inline">2-column template</span></span>
</header>
<nav aria-label="Demo sidebar" class="flex flex-col gap-1.25 pt-8.5! [grid-area:sidebar] @max-[41rem]/stage:px-2! [&>a]:flex [&>a]:h-10 [&>a]:items-center [&>a]:gap-2.5 [&>a]:rounded-lg [&>a]:px-2.5 [&>a]:text-[12.5px] [&>a]:font-semibold [&>a]:whitespace-nowrap [&>a]:text-tdl06-mut [&>a]:no-underline [&>a]:transition-colors [&>a:hover]:bg-tdl06-acc/8 [&>a:hover]:text-tdl06-ink [&>a:focus-visible]:outline-2 [&>a:focus-visible]:-outline-offset-2 [&>a:focus-visible]:outline-tdl06-acc [&>a[aria-current=page]]:bg-tdl06-acc/12 [&>a[aria-current=page]]:text-tdl06-acc @max-[41rem]/stage:[&>a]:justify-center @max-[41rem]/stage:[&>a]:px-0 [&_i]:size-4 [&_i]:flex-none [&_i]:rounded-[5px] [&_i]:bg-tdl06-line/45 [&>a[aria-current=page]_i]:bg-tdl06-acc"><b>sidebar</b>
<a href="#dash" aria-current="page"><i aria-hidden="true"></i><span class="@max-[41rem]/stage:sr-only">Dashboard</span></a>
<a href="#reports"><i aria-hidden="true"></i><span class="@max-[41rem]/stage:sr-only">Reports</span></a>
<a href="#team"><i aria-hidden="true"></i><span class="@max-[41rem]/stage:sr-only">Team</span></a>
<a href="#settings"><i aria-hidden="true"></i><span class="@max-[41rem]/stage:sr-only">Settings</span></a>
</nav>
<main class="pt-9! [grid-area:main]"><b>main</b>
<div aria-hidden="true" class="grid gap-3 *:block *:h-3.75 *:w-(--w) *:rounded-full *:bg-tdl06-line/25"><span style="--w:72%"></span><span style="--w:94%"></span><span style="--w:58%"></span><span style="--w:86%"></span><span style="--w:66%"></span></div>
<div aria-hidden="true" class="mt-5 grid grid-cols-3 gap-3 *:h-16 *:rounded-lg *:border *:border-tdl06-line/25 *:bg-white/70"><span></span><span></span><span></span></div>
</main>
<aside class="flex flex-col gap-3.5 pt-9! [grid-area:aside] @max-[41rem]/stage:flex-row @max-[41rem]/stage:pt-8!"><b>aside</b>
<p class="grid gap-1.75 text-xs font-semibold text-tdl06-mut @max-[41rem]/stage:flex-1">Quota · 64%<span class="h-2 overflow-hidden rounded-full bg-tdl06-line/22"><i class="block h-full w-[64%] rounded-full bg-linear-to-r from-tdl06-acc to-tdl06-line"></i></span></p>
<p class="grid gap-1.75 text-xs font-semibold text-tdl06-mut @max-[41rem]/stage:flex-1">Storage · 38%<span class="h-2 overflow-hidden rounded-full bg-tdl06-line/22"><i class="block h-full w-[38%] rounded-full bg-linear-to-r from-tdl06-acc to-tdl06-line"></i></span></p>
</aside>
<footer class="flex items-center gap-3 overflow-hidden pl-22! [grid-area:footer]"><b>footer</b>
<code class="truncate font-tdl06-mono text-[10.5px] font-semibold text-tdl06-mut @max-[41rem]/stage:hidden">'header header header' 'sidebar main aside' 'footer footer footer'</code>
<code class="hidden truncate font-tdl06-mono text-[10.5px] font-semibold text-tdl06-mut @max-[41rem]/stage:block">'header header' 'sidebar main' 'aside aside' 'footer footer'</code>
</footer>
</div>
</div>
<p class="mt-2 flex items-center gap-2 text-xs font-semibold text-tdl06-mut"><span aria-hidden="true" class="font-tdl06-mono text-tdl06-acc">⤡</span>Drag the stage's bottom-right corner to cross the 41rem breakpoint</p>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tdl06-bg: #eef2f7;
--color-tdl06-bg: oklch(0.96 0.01 245);
--color-tdl06-paper: #f8fafc;
--color-tdl06-paper: oklch(0.982 0.005 245);
--color-tdl06-dot: #dbe3ee;
--color-tdl06-dot: oklch(0.91 0.015 250);
--color-tdl06-edge: #d8dfe9;
--color-tdl06-edge: oklch(0.9 0.015 250);
--color-tdl06-ink: #2b3445;
--color-tdl06-ink: oklch(0.3 0.03 255);
--color-tdl06-mut: #556079;
--color-tdl06-mut: oklch(0.48 0.04 260);
--color-tdl06-line: #4f7cc6;
--color-tdl06-line: oklch(0.58 0.12 258);
--color-tdl06-fill: #e9f0fb;
--color-tdl06-fill: oklch(0.95 0.02 255);
--color-tdl06-fill2: #f5f8fd;
--color-tdl06-fill2: oklch(0.977 0.01 255);
--color-tdl06-hover: #eef3fd;
--color-tdl06-hover: oklch(0.965 0.018 260);
--color-tdl06-acc: #2c5fd6;
--color-tdl06-acc: oklch(0.53 0.18 262);
--font-tdl06-sans: 'Space Grotesk', system-ui, sans-serif;
--font-tdl06-mono: 'JetBrains Mono', ui-monospace, monospace;
}
.tdl-06 {
width: 100%;
min-height: 100svh;
}
@media (prefers-reduced-motion: reduce) {
.tdl-06 * {
transition: none !important;
}
}
```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 CSS Grid Template Areas Dashboard Layout
Source: https://codefronts.com/layouts/tailwind-css-dashboard-layouts/tailwind-css-grid-template-areas-dashboard-layout/
Tailwind has no grid-areas utility — and this demo shows you do not need one. The whole header / sidebar / main / aside / footer shell is an arbitrary property, [grid-template-areas:'header_header_header'_'sidebar_main_aside'_'footer_footer_footer'], re-drawn under @max-[41rem]/stage:. Drag the stage edge and a live badge reports which template is active.
## HTML
```html
<section class="tdl-06 grid w-full min-h-svh place-items-center bg-tdl06-bg p-3 font-tdl06-sans text-tdl06-ink antialiased sm:p-5" aria-label="grid-template-areas dashboard demo">
<div class="@container/stage h-[calc(100svh-2.5rem)] min-h-[32rem] w-full max-w-full min-w-[20rem] resize-x overflow-auto rounded-2xl border border-tdl06-edge bg-tdl06-paper bg-[radial-gradient(var(--color-tdl06-dot)_1px,transparent_1px)] bg-size-[16px_16px] p-3.5">
<div class="grid h-full grid-cols-[12.5rem_minmax(0,1fr)_14.5rem] grid-rows-[3.375rem_minmax(0,1fr)_2.75rem] gap-3 [grid-template-areas:'header_header_header'_'sidebar_main_aside'_'footer_footer_footer'] @max-[41rem]/stage:grid-cols-[4rem_minmax(0,1fr)] @max-[41rem]/stage:grid-rows-[3.375rem_minmax(0,1fr)_auto_2.75rem] @max-[41rem]/stage:[grid-template-areas:'header_header'_'sidebar_main'_'aside_aside'_'footer_footer'] *:relative *:min-w-0 *:rounded-xl *:border-[1.5px] *:border-dashed *:border-tdl06-line/55 *:bg-linear-150 *:from-tdl06-fill2 *:to-tdl06-fill *:px-3.5 *:py-3 *:transition-colors *:hover:border-tdl06-acc *:hover:bg-tdl06-hover [&>*>b]:absolute [&>*>b]:-top-px [&>*>b]:-left-px [&>*>b]:rounded-[10px_0_10px_0] [&>*>b]:bg-tdl06-line [&>*>b]:px-2.5 [&>*>b]:py-1 [&>*>b]:font-tdl06-mono [&>*>b]:text-[10px] [&>*>b]:font-bold [&>*>b]:tracking-[0.06em] [&>*>b]:text-white [&>*:hover>b]:bg-tdl06-acc">
<header class="flex items-center gap-3.5 pl-24! [grid-area:header]"><b>header</b><span class="truncate font-tdl06-mono text-[11px] font-semibold text-tdl06-mut">[grid-area:header]</span>
<span class="ml-auto flex flex-none items-center gap-1.5 rounded-full bg-tdl06-acc/10 px-2.5 py-1 text-[10.5px] font-bold tracking-[0.06em] text-tdl06-acc uppercase"><i aria-hidden="true" class="size-1.5 rounded-full bg-tdl06-acc"></i><span class="@max-[41rem]/stage:hidden">3-column template</span><span class="hidden @max-[41rem]/stage:inline">2-column template</span></span>
</header>
<nav aria-label="Demo sidebar" class="flex flex-col gap-1.25 pt-8.5! [grid-area:sidebar] @max-[41rem]/stage:px-2! [&>a]:flex [&>a]:h-10 [&>a]:items-center [&>a]:gap-2.5 [&>a]:rounded-lg [&>a]:px-2.5 [&>a]:text-[12.5px] [&>a]:font-semibold [&>a]:whitespace-nowrap [&>a]:text-tdl06-mut [&>a]:no-underline [&>a]:transition-colors [&>a:hover]:bg-tdl06-acc/8 [&>a:hover]:text-tdl06-ink [&>a:focus-visible]:outline-2 [&>a:focus-visible]:-outline-offset-2 [&>a:focus-visible]:outline-tdl06-acc [&>a[aria-current=page]]:bg-tdl06-acc/12 [&>a[aria-current=page]]:text-tdl06-acc @max-[41rem]/stage:[&>a]:justify-center @max-[41rem]/stage:[&>a]:px-0 [&_i]:size-4 [&_i]:flex-none [&_i]:rounded-[5px] [&_i]:bg-tdl06-line/45 [&>a[aria-current=page]_i]:bg-tdl06-acc"><b>sidebar</b>
<a href="#dash" aria-current="page"><i aria-hidden="true"></i><span class="@max-[41rem]/stage:sr-only">Dashboard</span></a>
<a href="#reports"><i aria-hidden="true"></i><span class="@max-[41rem]/stage:sr-only">Reports</span></a>
<a href="#team"><i aria-hidden="true"></i><span class="@max-[41rem]/stage:sr-only">Team</span></a>
<a href="#settings"><i aria-hidden="true"></i><span class="@max-[41rem]/stage:sr-only">Settings</span></a>
</nav>
<main class="pt-9! [grid-area:main]"><b>main</b>
<div aria-hidden="true" class="grid gap-3 *:block *:h-3.75 *:w-(--w) *:rounded-full *:bg-tdl06-line/25"><span style="--w:72%"></span><span style="--w:94%"></span><span style="--w:58%"></span><span style="--w:86%"></span><span style="--w:66%"></span></div>
<div aria-hidden="true" class="mt-5 grid grid-cols-3 gap-3 *:h-16 *:rounded-lg *:border *:border-tdl06-line/25 *:bg-white/70"><span></span><span></span><span></span></div>
</main>
<aside class="flex flex-col gap-3.5 pt-9! [grid-area:aside] @max-[41rem]/stage:flex-row @max-[41rem]/stage:pt-8!"><b>aside</b>
<p class="grid gap-1.75 text-xs font-semibold text-tdl06-mut @max-[41rem]/stage:flex-1">Quota · 64%<span class="h-2 overflow-hidden rounded-full bg-tdl06-line/22"><i class="block h-full w-[64%] rounded-full bg-linear-to-r from-tdl06-acc to-tdl06-line"></i></span></p>
<p class="grid gap-1.75 text-xs font-semibold text-tdl06-mut @max-[41rem]/stage:flex-1">Storage · 38%<span class="h-2 overflow-hidden rounded-full bg-tdl06-line/22"><i class="block h-full w-[38%] rounded-full bg-linear-to-r from-tdl06-acc to-tdl06-line"></i></span></p>
</aside>
<footer class="flex items-center gap-3 overflow-hidden pl-22! [grid-area:footer]"><b>footer</b>
<code class="truncate font-tdl06-mono text-[10.5px] font-semibold text-tdl06-mut @max-[41rem]/stage:hidden">'header header header' 'sidebar main aside' 'footer footer footer'</code>
<code class="hidden truncate font-tdl06-mono text-[10.5px] font-semibold text-tdl06-mut @max-[41rem]/stage:block">'header header' 'sidebar main' 'aside aside' 'footer footer'</code>
</footer>
</div>
</div>
<p class="mt-2 flex items-center gap-2 text-xs font-semibold text-tdl06-mut"><span aria-hidden="true" class="font-tdl06-mono text-tdl06-acc">⤡</span>Drag the stage's bottom-right corner to cross the 41rem breakpoint</p>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tdl06-bg: #eef2f7;
--color-tdl06-bg: oklch(0.96 0.01 245);
--color-tdl06-paper: #f8fafc;
--color-tdl06-paper: oklch(0.982 0.005 245);
--color-tdl06-dot: #dbe3ee;
--color-tdl06-dot: oklch(0.91 0.015 250);
--color-tdl06-edge: #d8dfe9;
--color-tdl06-edge: oklch(0.9 0.015 250);
--color-tdl06-ink: #2b3445;
--color-tdl06-ink: oklch(0.3 0.03 255);
--color-tdl06-mut: #556079;
--color-tdl06-mut: oklch(0.48 0.04 260);
--color-tdl06-line: #4f7cc6;
--color-tdl06-line: oklch(0.58 0.12 258);
--color-tdl06-fill: #e9f0fb;
--color-tdl06-fill: oklch(0.95 0.02 255);
--color-tdl06-fill2: #f5f8fd;
--color-tdl06-fill2: oklch(0.977 0.01 255);
--color-tdl06-hover: #eef3fd;
--color-tdl06-hover: oklch(0.965 0.018 260);
--color-tdl06-acc: #2c5fd6;
--color-tdl06-acc: oklch(0.53 0.18 262);
--font-tdl06-sans: 'Space Grotesk', system-ui, sans-serif;
--font-tdl06-mono: 'JetBrains Mono', ui-monospace, monospace;
}
.tdl-06 {
width: 100%;
min-height: 100svh;
}
@media (prefers-reduced-motion: reduce) {
.tdl-06 * {
transition: none !important;
}
}
```How this works
Arbitrary properties are the escape hatch. Anything Tailwind lacks can be written as [property:value]; spaces inside the value are underscores:
<div class="grid grid-cols-[12.5rem_minmax(0,1fr)_14.5rem]
grid-rows-[3.375rem_minmax(0,1fr)_2.75rem]
[grid-template-areas:'header_header_header'_'sidebar_main_aside'_'footer_footer_footer']">Each region names itself. [grid-area:header], [grid-area:main]… Because placement is by name, the source order can stay semantic (header, nav, main, aside, footer) whatever the visual order.
The narrow template. Under 41rem of stage width, the same element swaps columns, rows and areas with three @max-[41rem]/stage: utilities; the sidebar's labels become sr-only so the rail stays accessible, and the badge spans flip with hidden @max-[41rem]/stage:inline.
Make it yours
- Move a region: edit the area strings — e.g. put
asideon the left with'aside_main_sidebar'. - Want a utility? Add
@utility grid-areas-shell { grid-template-areas: …; }to the stylesheet and usegrid-areas-shell. - Breakpoint: change
41remin every@max-[41rem]/stage:(template, columns, rows, labels, badge). - Remove the debug look: drop the dashed borders and the corner tags (
<b>elements).
Gotchas — read before shipping
- Every row string must have the same number of cells, and each area must form a rectangle — otherwise the whole declaration is invalid and silently ignored.
- An underscore you actually want (rare in area names) must be escaped as
\_. resizeneedsoverflowother thanvisible; the handle is the browser's own and sits in the bottom-right corner.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
Tailwind v4 floor. resize on non-textarea elements is unsupported on iOS Safari (the layout still works; only dragging is unavailable).