Pure TailwindMIT licensed

Tailwind CSS Top Navigation Bar Dashboard Layout with Tabs

The GitHub / Stripe school: no sidebar — a global top bar, a sticky tab strip with an animated underline, and content in a centred w-[min(100%_-_3rem,57.5rem)] column. Tabs are radios: group-has-[#tdl17-t2:checked]/page:grid swaps the panes and has-checked:after:scale-x-100 slides each underline in. New in the port: panes fade in with starting:, the tab strip scrolls horizontally on phones, and invoices and plans gained real status and “Current” affordances.

Live Demo
Plain CSSTailwind v4
Try it

Mosaic by Cruip: a complete Tailwind admin dashboard template in HTML, React, Next.js and Vue · $69

Cruip · Mosaic by Cruip · Affiliate link

View Mosaic dashboard

The code

<section class="tdl-17 w-full min-h-svh bg-tdl17-bg font-tdl17-sans text-tdl17-ink antialiased" aria-label="Top-bar navigation dashboard demo">
  <div class="group/page flex h-svh min-h-[32rem] flex-col overflow-hidden">
    <header class="flex h-14 flex-none items-center gap-3.5 bg-tdl17-bar px-4.5 text-tdl17-barink">
      <span aria-hidden="true" class="size-6 flex-none rounded-full bg-[conic-gradient(from_200deg,var(--color-tdl17-acc),var(--color-tdl17-acc2),var(--color-tdl17-acc))]"></span>
      <nav aria-label="Breadcrumb" class="flex min-w-0 items-center gap-2 text-[14px]"><a href="#org" class="truncate rounded-sm font-semibold text-tdl17-barmut no-underline underline-offset-3 hover:text-white hover:underline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tdl17-acc2">acme-inc</a><span aria-hidden="true" class="opacity-45">/</span><b class="font-bold">billing</b></nav>
      <label class="ml-auto flex h-9 w-[min(16rem,40%)] items-center gap-2 rounded-lg border border-tdl17-baredge px-2.5 text-xs text-tdl17-barmut transition focus-within:border-tdl17-acc2 focus-within:bg-white/5 max-sm:hidden"><span class="sr-only">Jump to</span><input type="search" placeholder="Jump to…" class="min-w-0 flex-1 bg-transparent text-white outline-none placeholder:text-tdl17-barmut"><kbd class="rounded border border-tdl17-baredge px-1.5 font-sans text-[10px]">/</kbd></label>
      <span aria-hidden="true" class="grid size-8 flex-none place-items-center rounded-full bg-linear-140 from-tdl17-acc to-tdl17-acc3 text-[11px] font-bold text-white max-sm:ml-auto">AR</span>
    </header>
    <div class="flex min-h-0 flex-1 flex-col overflow-y-auto overscroll-contain [scrollbar-gutter:stable]">
      <div class="sticky top-0 z-10 border-b border-tdl17-edge bg-tdl17-bg/80 backdrop-blur-md">
        <fieldset class="mx-auto flex w-[min(100%_-_3rem,57.5rem)] gap-1 overflow-x-auto [scrollbar-width:none] [&>label]:relative [&>label]:flex-none [&>label]:cursor-pointer [&>label]:rounded-t-lg [&>label]:px-3.5 [&>label]:pt-3.5 [&>label]:pb-3 [&>label]:text-[14px] [&>label]:font-semibold [&>label]:text-tdl17-mut [&>label]:transition-colors [&>label:hover]:bg-tdl17-hover [&>label:hover]:text-tdl17-ink [&>label:has(:checked)]:text-tdl17-ink [&>label:has(:focus-visible)]:outline-2 [&>label:has(:focus-visible)]:-outline-offset-2 [&>label:has(:focus-visible)]:outline-tdl17-acc [&>label]:after:absolute [&>label]:after:inset-x-2 [&>label]:after:-bottom-px [&>label]:after:h-0.75 [&>label]:after:scale-x-0 [&>label]:after:rounded-full [&>label]:after:bg-tdl17-acc [&>label]:after:transition-transform [&>label]:after:duration-250 [&>label]:after:ease-[cubic-bezier(.2,.7,.2,1)] [&>label]:after:content-[''] [&>label:has(:checked)]:after:scale-x-100">
          <legend class="sr-only">Billing sections</legend>
          <label><input class="sr-only" type="radio" name="tdl17" id="tdl17-t1" checked>Overview</label>
          <label><input class="sr-only" type="radio" name="tdl17" id="tdl17-t2">Plans</label>
          <label><input class="sr-only" type="radio" name="tdl17" id="tdl17-t3">Danger zone</label>
        </fieldset>
      </div>
      <main class="mx-auto w-[min(100%_-_3rem,57.5rem)] pt-6 pb-8 *:gap-4 *:transition-[opacity,translate] *:duration-300 *:starting:translate-y-1.5 *:starting:opacity-0 [&_h1]:text-[22px] [&_h1]:font-bold [&_h1]:tracking-tight [&_article]:grid [&_article]:content-start [&_article]:justify-items-start [&_article]:gap-2 [&_article]:rounded-xl [&_article]:border [&_article]:border-tdl17-edge [&_article]:bg-tdl17-panel [&_article]:px-5 [&_article]:py-4.5 [&_h3]:text-[11px] [&_h3]:font-bold [&_h3]:tracking-[0.1em] [&_h3]:text-tdl17-mut [&_h3]:uppercase [&_.big]:text-[28px] [&_.big]:font-bold [&_.big]:tracking-tight [&_.big]:tabular-nums [&_article_small]:text-[13px] [&_article_small]:text-tdl17-mut [&_button]:h-10 [&_button]:cursor-pointer [&_button]:rounded-lg [&_button]:px-3.5 [&_button]:text-[13px] [&_button]:font-semibold [&_button]:transition-colors [&_button:focus-visible]:outline-2 [&_button:focus-visible]:outline-offset-2 [&_button:focus-visible]:outline-tdl17-acc [&_.ghost]:border [&_.ghost]:border-tdl17-edge [&_.ghost]:bg-tdl17-bg [&_.ghost:hover]:border-tdl17-mut/50">
        <div class="hidden group-has-[#tdl17-t1:checked]/page:grid">
          <h1>Billing overview</h1>
          <div class="grid grid-cols-[repeat(auto-fit,minmax(min(15rem,100%),1fr))] gap-4">
            <article><h3>Current plan</h3><p class="big">Team</p><small>$96 / month · renews Oct 12</small><button type="button" class="ghost">Manage plan</button></article>
            <article><h3>Usage this cycle</h3><p class="big">64%</p><span aria-hidden="true" class="h-1.75 w-full overflow-hidden rounded-full bg-tdl17-track"><i class="block h-full w-[64%] rounded-full bg-linear-to-r from-tdl17-acc to-tdl17-acc2"></i></span><small>12,800 / 20,000 build minutes</small></article>
          </div>
          <article>
            <h3>Invoices</h3>
            <ul class="w-full [&>li]:flex [&>li]:items-center [&>li]:gap-3 [&>li]:border-b [&>li]:border-tdl17-edge/55 [&>li]:py-2.5 [&>li]:text-[14px] [&>li:last-child]:border-b-0 [&_b]:mr-auto [&_b]:font-semibold [&_.amt]:text-tdl17-mut [&_.amt]:tabular-nums [&_a]:rounded-sm [&_a]:text-[13px] [&_a]:font-bold [&_a]:text-tdl17-acc [&_a]:no-underline [&_a]:underline-offset-3 [&_a:hover]:underline [&_a:focus-visible]:outline-2 [&_a:focus-visible]:outline-offset-2 [&_a:focus-visible]:outline-tdl17-acc [&_.paid]:rounded-full [&_.paid]:bg-tdl17-good/12 [&_.paid]:px-2 [&_.paid]:py-0.5 [&_.paid]:text-[11px] [&_.paid]:font-bold [&_.paid]:text-tdl17-good">
              <li><b>#0093 · September 2026</b><span class="paid">Paid</span><span class="amt">$96.00</span><a href="#dl">PDF</a></li>
              <li><b>#0091 · August 2026</b><span class="paid">Paid</span><span class="amt">$96.00</span><a href="#dl">PDF</a></li>
              <li><b>#0087 · July 2026</b><span class="paid">Paid</span><span class="amt">$84.00</span><a href="#dl">PDF</a></li>
            </ul>
          </article>
        </div>
        <div class="hidden group-has-[#tdl17-t2:checked]/page:grid">
          <h1>Plans</h1>
          <div class="grid grid-cols-[repeat(auto-fit,minmax(min(14rem,100%),1fr))] gap-4">
            <article><h3>Starter</h3><p class="big">$0</p><small>2 seats · 2k minutes</small><button type="button" class="ghost">Downgrade</button></article>
            <article class="relative border-tdl17-acc/60! shadow-[0_0_0_3px_var(--color-tdl17-ring)]"><span class="absolute top-3.5 right-3.5 rounded-full bg-tdl17-acc px-2 py-0.5 text-[10.5px] font-bold text-white">Current</span><h3>Team</h3><p class="big">$96</p><small>10 seats · 20k minutes</small><button type="button" class="ghost" disabled aria-disabled="true">Your plan</button></article>
            <article><h3>Scale</h3><p class="big">$290</p><small>25 seats · 80k minutes</small><button type="button" class="bg-tdl17-acc text-white hover:bg-tdl17-accdark">Upgrade</button></article>
          </div>
        </div>
        <div class="hidden group-has-[#tdl17-t3:checked]/page:grid">
          <h1>Danger zone</h1>
          <article class="border-tdl17-red/35!"><h3>Cancel subscription</h3><p class="text-[13.5px]/[1.55] text-tdl17-mut">Billing stops at cycle end; data is retained for 90 days.</p><button type="button" class="border border-tdl17-red/45 bg-tdl17-red/7 text-tdl17-red hover:bg-tdl17-red/14">Cancel plan…</button></article>
          <article class="border-tdl17-red/35!"><h3>Delete organization</h3><p class="text-[13.5px]/[1.55] text-tdl17-mut">Permanently removes acme-inc, its repositories and audit history.</p><button type="button" class="border border-tdl17-red/45 bg-tdl17-red/7 text-tdl17-red hover:bg-tdl17-red/14">Delete organization…</button></article>
        </div>
      </main>
    </div>
  </div>
</section>
@import "tailwindcss";

@theme {
  --color-tdl17-bg: #f8f9fb;
  --color-tdl17-bg: oklch(0.98 0.003 250);
  --color-tdl17-panel: #ffffff;
  --color-tdl17-panel: oklch(1 0 0);
  --color-tdl17-hover: #eef0f3;
  --color-tdl17-hover: oklch(0.948 0.006 250);
  --color-tdl17-track: #e9ecf0;
  --color-tdl17-track: oklch(0.935 0.006 250);
  --color-tdl17-edge: #dfe3e8;
  --color-tdl17-edge: oklch(0.905 0.008 250);
  --color-tdl17-ink: #22272f;
  --color-tdl17-ink: oklch(0.25 0.015 250);
  --color-tdl17-mut: #575e6a;
  --color-tdl17-mut: oklch(0.47 0.015 250);
  --color-tdl17-bar: #1b2130;
  --color-tdl17-bar: oklch(0.23 0.02 260);
  --color-tdl17-barink: #f0f2f5;
  --color-tdl17-barink: oklch(0.96 0.005 250);
  --color-tdl17-barmut: #b6bdc8;
  --color-tdl17-barmut: oklch(0.8 0.015 250);
  --color-tdl17-baredge: #3b4354;
  --color-tdl17-baredge: oklch(0.37 0.02 260);
  --color-tdl17-acc: #2962c4;
  --color-tdl17-acc: oklch(0.52 0.16 257);
  --color-tdl17-accdark: #1f4e9e;
  --color-tdl17-accdark: oklch(0.45 0.14 257);
  --color-tdl17-acc2: #43aecf;
  --color-tdl17-acc2: oklch(0.71 0.11 215);
  --color-tdl17-acc3: #8b5cd6;
  --color-tdl17-acc3: oklch(0.6 0.16 295);
  --color-tdl17-ring: #dbe6f8;
  --color-tdl17-ring: oklch(0.92 0.03 257);
  --color-tdl17-good: #17804a;
  --color-tdl17-good: oklch(0.52 0.13 155);
  --color-tdl17-red: #c3352b;
  --color-tdl17-red: oklch(0.55 0.19 27);
  --font-tdl17-sans: 'Mona Sans', system-ui, sans-serif;
}

.tdl-17 {
  width: 100%;
  min-height: 100svh;
}

@media (prefers-reduced-motion: reduce) {
  .tdl-17 * {
    transition: none !important;
  }
}

Setup — do this once per project

Skip this if your project already runs Tailwind v4.

1Load Tailwind
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>

Compiles in the browser — perfect for a CodePen or a quick test, not for production.

2Add the stylesheetRequiredthe @theme block is what makes the custom utilities exist
@import "tailwindcss";

@theme {
  --color-tdl17-bg: #f8f9fb;
  --color-tdl17-bg: oklch(0.98 0.003 250);
  --color-tdl17-panel: #ffffff;
  --color-tdl17-panel: oklch(1 0 0);
  --color-tdl17-hover: #eef0f3;
  --color-tdl17-hover: oklch(0.948 0.006 250);
  --color-tdl17-track: #e9ecf0;
  --color-tdl17-track: oklch(0.935 0.006 250);
  --color-tdl17-edge: #dfe3e8;
  --color-tdl17-edge: oklch(0.905 0.008 250);
  --color-tdl17-ink: #22272f;
  --color-tdl17-ink: oklch(0.25 0.015 250);
  --color-tdl17-mut: #575e6a;
  --color-tdl17-mut: oklch(0.47 0.015 250);
  --color-tdl17-bar: #1b2130;
  --color-tdl17-bar: oklch(0.23 0.02 260);
  --color-tdl17-barink: #f0f2f5;
  --color-tdl17-barink: oklch(0.96 0.005 250);
  --color-tdl17-barmut: #b6bdc8;
  --color-tdl17-barmut: oklch(0.8 0.015 250);
  --color-tdl17-baredge: #3b4354;
  --color-tdl17-baredge: oklch(0.37 0.02 260);
  --color-tdl17-acc: #2962c4;
  --color-tdl17-acc: oklch(0.52 0.16 257);
  --color-tdl17-accdark: #1f4e9e;
  --color-tdl17-accdark: oklch(0.45 0.14 257);
  --color-tdl17-acc2: #43aecf;
  --color-tdl17-acc2: oklch(0.71 0.11 215);
  --color-tdl17-acc3: #8b5cd6;
  --color-tdl17-acc3: oklch(0.6 0.16 295);
  --color-tdl17-ring: #dbe6f8;
  --color-tdl17-ring: oklch(0.92 0.03 257);
  --color-tdl17-good: #17804a;
  --color-tdl17-good: oklch(0.52 0.13 155);
  --color-tdl17-red: #c3352b;
  --color-tdl17-red: oklch(0.55 0.19 27);
  --font-tdl17-sans: 'Mona Sans', system-ui, sans-serif;
}

.tdl-17 {
  width: 100%;
  min-height: 100svh;
}

@media (prefers-reduced-motion: reduce) {
  .tdl-17 * {
    transition: none !important;
  }
}
3Fonts used by this demooptional — skip if you have your own type stack
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Mona+Sans:wght@400..800&display=swap">

What changed in the port

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

  • Three .cdl-17:has(#cdl17-tN:checked) .cdl-17__pane--N rules became group-has-[#tdl17-tN:checked]/page:grid; the tab underline is a single after: stack on the fieldset's labels.
  • width:min(100% - 48px, 920px) became w-[min(100%_-_3rem,57.5rem)] — underscores carry the spaces CSS requires around the minus sign.
  • UI upgrade from the CSS original: panes rise in via starting:; the tab strip scrolls horizontally on narrow screens instead of wrapping; the fake “Jump to…” pill is a real search input; invoices show Paid status; the current plan carries a “Current” badge and a disabled button instead of a pressed ghost button.
  • UI upgrade: tabs and buttons are 40px+ tall, the underline is thicker (3px) for visibility, and muted copy darkened to 6.6:1.
Paste this into ChatGPT, Claude, Cursor, or any coding assistant. The block below is pre-framed with everything the AI needs to integrate this demo into your project — markup, styles, scoping notes, and the source URL. Hit Copy and paste straight into your chat.
Here's a working CSS demo from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Tailwind CSS Top Navigation Bar Dashboard Layout with Tabs
Source: https://codefronts.com/layouts/tailwind-css-dashboard-layouts/tailwind-css-top-navigation-bar-dashboard-layout-tabs/

The GitHub / Stripe school: no sidebar &mdash; a global top bar, a sticky tab strip with an animated underline, and content in a centred w-[min(100%_-_3rem,57.5rem)] column. Tabs are radios: group-has-[#tdl17-t2:checked]/page:grid swaps the panes and has-checked:after:scale-x-100 slides each underline in. New in the port: panes fade in with starting:, the tab strip scrolls horizontally on phones, and invoices and plans gained real status and “Current” affordances.
## HTML
```html
<section class="tdl-17 w-full min-h-svh bg-tdl17-bg font-tdl17-sans text-tdl17-ink antialiased" aria-label="Top-bar navigation dashboard demo">
  <div class="group/page flex h-svh min-h-[32rem] flex-col overflow-hidden">
    <header class="flex h-14 flex-none items-center gap-3.5 bg-tdl17-bar px-4.5 text-tdl17-barink">
      <span aria-hidden="true" class="size-6 flex-none rounded-full bg-[conic-gradient(from_200deg,var(--color-tdl17-acc),var(--color-tdl17-acc2),var(--color-tdl17-acc))]"></span>
      <nav aria-label="Breadcrumb" class="flex min-w-0 items-center gap-2 text-[14px]"><a href="#org" class="truncate rounded-sm font-semibold text-tdl17-barmut no-underline underline-offset-3 hover:text-white hover:underline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tdl17-acc2">acme-inc</a><span aria-hidden="true" class="opacity-45">/</span><b class="font-bold">billing</b></nav>
      <label class="ml-auto flex h-9 w-[min(16rem,40%)] items-center gap-2 rounded-lg border border-tdl17-baredge px-2.5 text-xs text-tdl17-barmut transition focus-within:border-tdl17-acc2 focus-within:bg-white/5 max-sm:hidden"><span class="sr-only">Jump to</span><input type="search" placeholder="Jump to…" class="min-w-0 flex-1 bg-transparent text-white outline-none placeholder:text-tdl17-barmut"><kbd class="rounded border border-tdl17-baredge px-1.5 font-sans text-[10px]">/</kbd></label>
      <span aria-hidden="true" class="grid size-8 flex-none place-items-center rounded-full bg-linear-140 from-tdl17-acc to-tdl17-acc3 text-[11px] font-bold text-white max-sm:ml-auto">AR</span>
    </header>
    <div class="flex min-h-0 flex-1 flex-col overflow-y-auto overscroll-contain [scrollbar-gutter:stable]">
      <div class="sticky top-0 z-10 border-b border-tdl17-edge bg-tdl17-bg/80 backdrop-blur-md">
        <fieldset class="mx-auto flex w-[min(100%_-_3rem,57.5rem)] gap-1 overflow-x-auto [scrollbar-width:none] [&>label]:relative [&>label]:flex-none [&>label]:cursor-pointer [&>label]:rounded-t-lg [&>label]:px-3.5 [&>label]:pt-3.5 [&>label]:pb-3 [&>label]:text-[14px] [&>label]:font-semibold [&>label]:text-tdl17-mut [&>label]:transition-colors [&>label:hover]:bg-tdl17-hover [&>label:hover]:text-tdl17-ink [&>label:has(:checked)]:text-tdl17-ink [&>label:has(:focus-visible)]:outline-2 [&>label:has(:focus-visible)]:-outline-offset-2 [&>label:has(:focus-visible)]:outline-tdl17-acc [&>label]:after:absolute [&>label]:after:inset-x-2 [&>label]:after:-bottom-px [&>label]:after:h-0.75 [&>label]:after:scale-x-0 [&>label]:after:rounded-full [&>label]:after:bg-tdl17-acc [&>label]:after:transition-transform [&>label]:after:duration-250 [&>label]:after:ease-[cubic-bezier(.2,.7,.2,1)] [&>label]:after:content-[''] [&>label:has(:checked)]:after:scale-x-100">
          <legend class="sr-only">Billing sections</legend>
          <label><input class="sr-only" type="radio" name="tdl17" id="tdl17-t1" checked>Overview</label>
          <label><input class="sr-only" type="radio" name="tdl17" id="tdl17-t2">Plans</label>
          <label><input class="sr-only" type="radio" name="tdl17" id="tdl17-t3">Danger zone</label>
        </fieldset>
      </div>
      <main class="mx-auto w-[min(100%_-_3rem,57.5rem)] pt-6 pb-8 *:gap-4 *:transition-[opacity,translate] *:duration-300 *:starting:translate-y-1.5 *:starting:opacity-0 [&_h1]:text-[22px] [&_h1]:font-bold [&_h1]:tracking-tight [&_article]:grid [&_article]:content-start [&_article]:justify-items-start [&_article]:gap-2 [&_article]:rounded-xl [&_article]:border [&_article]:border-tdl17-edge [&_article]:bg-tdl17-panel [&_article]:px-5 [&_article]:py-4.5 [&_h3]:text-[11px] [&_h3]:font-bold [&_h3]:tracking-[0.1em] [&_h3]:text-tdl17-mut [&_h3]:uppercase [&_.big]:text-[28px] [&_.big]:font-bold [&_.big]:tracking-tight [&_.big]:tabular-nums [&_article_small]:text-[13px] [&_article_small]:text-tdl17-mut [&_button]:h-10 [&_button]:cursor-pointer [&_button]:rounded-lg [&_button]:px-3.5 [&_button]:text-[13px] [&_button]:font-semibold [&_button]:transition-colors [&_button:focus-visible]:outline-2 [&_button:focus-visible]:outline-offset-2 [&_button:focus-visible]:outline-tdl17-acc [&_.ghost]:border [&_.ghost]:border-tdl17-edge [&_.ghost]:bg-tdl17-bg [&_.ghost:hover]:border-tdl17-mut/50">
        <div class="hidden group-has-[#tdl17-t1:checked]/page:grid">
          <h1>Billing overview</h1>
          <div class="grid grid-cols-[repeat(auto-fit,minmax(min(15rem,100%),1fr))] gap-4">
            <article><h3>Current plan</h3><p class="big">Team</p><small>$96 / month · renews Oct 12</small><button type="button" class="ghost">Manage plan</button></article>
            <article><h3>Usage this cycle</h3><p class="big">64%</p><span aria-hidden="true" class="h-1.75 w-full overflow-hidden rounded-full bg-tdl17-track"><i class="block h-full w-[64%] rounded-full bg-linear-to-r from-tdl17-acc to-tdl17-acc2"></i></span><small>12,800 / 20,000 build minutes</small></article>
          </div>
          <article>
            <h3>Invoices</h3>
            <ul class="w-full [&>li]:flex [&>li]:items-center [&>li]:gap-3 [&>li]:border-b [&>li]:border-tdl17-edge/55 [&>li]:py-2.5 [&>li]:text-[14px] [&>li:last-child]:border-b-0 [&_b]:mr-auto [&_b]:font-semibold [&_.amt]:text-tdl17-mut [&_.amt]:tabular-nums [&_a]:rounded-sm [&_a]:text-[13px] [&_a]:font-bold [&_a]:text-tdl17-acc [&_a]:no-underline [&_a]:underline-offset-3 [&_a:hover]:underline [&_a:focus-visible]:outline-2 [&_a:focus-visible]:outline-offset-2 [&_a:focus-visible]:outline-tdl17-acc [&_.paid]:rounded-full [&_.paid]:bg-tdl17-good/12 [&_.paid]:px-2 [&_.paid]:py-0.5 [&_.paid]:text-[11px] [&_.paid]:font-bold [&_.paid]:text-tdl17-good">
              <li><b>#0093 · September 2026</b><span class="paid">Paid</span><span class="amt">$96.00</span><a href="#dl">PDF</a></li>
              <li><b>#0091 · August 2026</b><span class="paid">Paid</span><span class="amt">$96.00</span><a href="#dl">PDF</a></li>
              <li><b>#0087 · July 2026</b><span class="paid">Paid</span><span class="amt">$84.00</span><a href="#dl">PDF</a></li>
            </ul>
          </article>
        </div>
        <div class="hidden group-has-[#tdl17-t2:checked]/page:grid">
          <h1>Plans</h1>
          <div class="grid grid-cols-[repeat(auto-fit,minmax(min(14rem,100%),1fr))] gap-4">
            <article><h3>Starter</h3><p class="big">$0</p><small>2 seats · 2k minutes</small><button type="button" class="ghost">Downgrade</button></article>
            <article class="relative border-tdl17-acc/60! shadow-[0_0_0_3px_var(--color-tdl17-ring)]"><span class="absolute top-3.5 right-3.5 rounded-full bg-tdl17-acc px-2 py-0.5 text-[10.5px] font-bold text-white">Current</span><h3>Team</h3><p class="big">$96</p><small>10 seats · 20k minutes</small><button type="button" class="ghost" disabled aria-disabled="true">Your plan</button></article>
            <article><h3>Scale</h3><p class="big">$290</p><small>25 seats · 80k minutes</small><button type="button" class="bg-tdl17-acc text-white hover:bg-tdl17-accdark">Upgrade</button></article>
          </div>
        </div>
        <div class="hidden group-has-[#tdl17-t3:checked]/page:grid">
          <h1>Danger zone</h1>
          <article class="border-tdl17-red/35!"><h3>Cancel subscription</h3><p class="text-[13.5px]/[1.55] text-tdl17-mut">Billing stops at cycle end; data is retained for 90 days.</p><button type="button" class="border border-tdl17-red/45 bg-tdl17-red/7 text-tdl17-red hover:bg-tdl17-red/14">Cancel plan…</button></article>
          <article class="border-tdl17-red/35!"><h3>Delete organization</h3><p class="text-[13.5px]/[1.55] text-tdl17-mut">Permanently removes acme-inc, its repositories and audit history.</p><button type="button" class="border border-tdl17-red/45 bg-tdl17-red/7 text-tdl17-red hover:bg-tdl17-red/14">Delete organization…</button></article>
        </div>
      </main>
    </div>
  </div>
</section>
```
## CSS
```css
@import "tailwindcss";

@theme {
  --color-tdl17-bg: #f8f9fb;
  --color-tdl17-bg: oklch(0.98 0.003 250);
  --color-tdl17-panel: #ffffff;
  --color-tdl17-panel: oklch(1 0 0);
  --color-tdl17-hover: #eef0f3;
  --color-tdl17-hover: oklch(0.948 0.006 250);
  --color-tdl17-track: #e9ecf0;
  --color-tdl17-track: oklch(0.935 0.006 250);
  --color-tdl17-edge: #dfe3e8;
  --color-tdl17-edge: oklch(0.905 0.008 250);
  --color-tdl17-ink: #22272f;
  --color-tdl17-ink: oklch(0.25 0.015 250);
  --color-tdl17-mut: #575e6a;
  --color-tdl17-mut: oklch(0.47 0.015 250);
  --color-tdl17-bar: #1b2130;
  --color-tdl17-bar: oklch(0.23 0.02 260);
  --color-tdl17-barink: #f0f2f5;
  --color-tdl17-barink: oklch(0.96 0.005 250);
  --color-tdl17-barmut: #b6bdc8;
  --color-tdl17-barmut: oklch(0.8 0.015 250);
  --color-tdl17-baredge: #3b4354;
  --color-tdl17-baredge: oklch(0.37 0.02 260);
  --color-tdl17-acc: #2962c4;
  --color-tdl17-acc: oklch(0.52 0.16 257);
  --color-tdl17-accdark: #1f4e9e;
  --color-tdl17-accdark: oklch(0.45 0.14 257);
  --color-tdl17-acc2: #43aecf;
  --color-tdl17-acc2: oklch(0.71 0.11 215);
  --color-tdl17-acc3: #8b5cd6;
  --color-tdl17-acc3: oklch(0.6 0.16 295);
  --color-tdl17-ring: #dbe6f8;
  --color-tdl17-ring: oklch(0.92 0.03 257);
  --color-tdl17-good: #17804a;
  --color-tdl17-good: oklch(0.52 0.13 155);
  --color-tdl17-red: #c3352b;
  --color-tdl17-red: oklch(0.55 0.19 27);
  --font-tdl17-sans: 'Mona Sans', system-ui, sans-serif;
}

.tdl-17 {
  width: 100%;
  min-height: 100svh;
}

@media (prefers-reduced-motion: reduce) {
  .tdl-17 * {
    transition: none !important;
  }
}
```

How this works

Tabs without script. Each tab is a <label> wrapping an sr-only radio. Its underline is an ::after that scales from 0 to 1 when the label has-checked; arrow keys switch tabs natively and focus draws on the label via has-focus-visible:.

<label class="relative after:absolute after:inset-x-2 after:-bottom-px after:h-0.5
  after:scale-x-0 after:bg-tdl17-acc after:transition-transform
  has-checked:after:scale-x-100">

Panes. The page is group/page; each pane is hidden until group-has-[#tdl17-tN:checked]/page:grid matches, and starting: gives it a short rise-in on every switch.

The breathing column. min(100% - 3rem, 57.5rem) is the whole responsive strategy: full width minus gutters on phones, capped reading width on desktops, with the tab row aligned to the same column.

Make it yours

  • Column width: 57.5rem in both w-[min(…)] utilities (tab row and content).
  • Add a tab: radio label + pane with group-has-[#new:checked]/page:grid.
  • Accent: --color-tdl17-acc; danger red: --color-tdl17-red.
  • Make tabs real routes: swap labels for <a aria-current="page"> and style with aria-[current=page]:after:scale-x-100.

Gotchas — read before shipping

  • CSS requires spaces around the minus sign inside min(), but class names cannot contain spaces — write them as underscores: w-[min(100%_-_3rem,57.5rem)].
  • Radio tabs are ideal for settings pages; for app-level navigation that should be linkable, use anchors.
  • backdrop-blur needs a translucent background to show anything — hence bg-tdl17-bg/80.

Browser support

ChromeSafariFirefoxEdge
117+17.5+129+117+

Floor is for the starting: pane fade; tabs, panes and layout work from the Tailwind v4 floor (Chrome 111 / Safari 16.4 / Firefox 128).

Techniques used in this demo

Utilitiesfirst-class utility or variant

Search CodeFronts

Loading…