30 Tailwind CSS Grid Layouts
05 / 30

All 30 in 30 Tailwind CSS Grid Layouts

  1. 01Tailwind Full-Bleed Article Layout for Long-Form Editorial
  2. 02Tailwind Docs Layout with Sticky Table of Contents
  3. 03Tailwind Photo Gallery Grid with auto-fill and Real Images
  4. 04Tailwind Holy Grail Page Layout for a News Site
  5. 05Tailwind Data Table with Subgrid Rows and Status Pills
  6. 06Tailwind Overlapping Card Hero for a Case Study
  7. 07Tailwind Help Center Layout with Fixed Sidebars
  8. 08Tailwind 12 Column Grid System for Marketing Pages
  9. 09Tailwind Bento Grid for a Product Feature Section
  10. 10Tailwind Magazine Spread Layout with Overlapping Headline
  11. 11Tailwind Responsive Card Grid for an Integrations Directory
  12. 12Tailwind CMS Category Grid that Compacts Itself with has()
  13. 13Tailwind Masonry Layout for a Saved Ideas Board
  14. 14Tailwind Hexagon Team Grid with clip-path Avatars
  15. 15Tailwind Subgrid Cards with Perfectly Aligned Buttons
  16. 16Tailwind Analytics Dashboard Layout with Grid App Shell
  17. 17Tailwind Pricing Table with Subgrid and a Featured Plan
  18. 18Tailwind Kanban Board with Scroll Snap Columns
  19. 19Tailwind Video Thumbnail Grid with Zero Layout Shift
  20. 20Tailwind Container Query Card for Reusable Article Teasers
  21. 21Tailwind Diagonal Section Band with skewY Counter-Skew
  22. 22Tailwind Asymmetric Poster Hero with Layered Grid Regions
  23. 23Tailwind Mosaic Photo Wall with a Designed Span Sequence
  24. 24Tailwind Dense Grid Packing for a Mixed-Size Asset Library
  25. 25Tailwind Onboarding Stepper with CSS Counters
  26. 26Tailwind macOS Window Layout with Vibrancy Sidebar
  27. 27Tailwind Scroll Snap Carousel with Peeking Slides
  28. 28Tailwind Status Map UI with Grid Coordinate Pins
  29. 29Tailwind Logo Wall with 1px Gap Hairline Dividers
  30. 30Tailwind Periodic Table Layout with Grid Coordinates
Pure TailwindMIT licensed

Tailwind Data Table with Subgrid Rows and Status Pills

A service-health table from an observability console: sparkline per service, tabular figures that line up by digit, status pills that never squash, and one master track list every row inherits with [grid-template-columns:subgrid].

Live Demo
Plain CSSTailwind v4
Try it

Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time

Untitled UI React · Affiliate link

Get Untitled UI Pro

The code

<section class="tgx-05 w-full min-h-svh bg-tgx05-bg font-tgx05-sans text-tgx05-ink p-6">
  <header class="flex items-end justify-between gap-4 flex-wrap mb-4">
    <div class="flex flex-col gap-1">
      <p class="font-tgx05-mono text-[0.68rem] tracking-[0.1em] uppercase text-tgx05-dim">Vantage · Observability</p>
      <h2 class="text-[1.25rem] font-semibold tracking-[-0.01em]">Service health — last 24h</h2>
    </div>
    <div class="flex items-center gap-2 text-[0.72rem] text-tgx05-dim">
      <span class="inline-flex items-center gap-1.5 rounded-full border border-tgx05-line px-2.5 py-1"><span class="size-1.5 rounded-full bg-tgx05-ok"></span>3 healthy</span>
      <span class="inline-flex items-center gap-1.5 rounded-full border border-tgx05-line px-2.5 py-1"><span class="size-1.5 rounded-full bg-tgx05-down"></span>1 failing</span>
    </div>
  </header>
  <div role="table" aria-label="Service health" class="grid grid-cols-[minmax(150px,1.6fr)_minmax(86px,0.8fr)_minmax(80px,0.7fr)_minmax(80px,0.7fr)_minmax(90px,0.8fr)_minmax(84px,max-content)] max-sm:grid-cols-[minmax(120px,1.6fr)_minmax(80px,1fr)_minmax(84px,max-content)] rounded-xl border border-tgx05-line overflow-hidden bg-tgx05-panel">
    <div role="row" class="col-span-full [grid-template-columns:subgrid] grid items-center gap-x-4 px-4 py-2.5 bg-tgx05-head text-[0.66rem] tracking-[0.12em] uppercase text-tgx05-dim">
      <span role="columnheader">Service</span>
      <span role="columnheader" class="max-sm:hidden">Trend</span>
      <span role="columnheader" class="text-right max-sm:hidden">Requests</span>
      <span role="columnheader" class="text-right max-sm:hidden">p95</span>
      <span role="columnheader" class="text-right">Errors</span>
      <span role="columnheader">Status</span>
    </div>
    <div role="row" class="col-span-full [grid-template-columns:subgrid] grid items-center gap-x-4 px-4 py-3 border-t border-tgx05-line text-[0.84rem] transition-colors hover:bg-tgx05-hover">
      <span role="cell" class="flex flex-col"><span class="font-medium">edge-gateway</span><span class="text-[0.7rem] text-tgx05-dim">eu-west-1 · 12 pods</span></span>
      <span role="cell" class="max-sm:hidden"><span class="grid grid-cols-8 items-end gap-[2px] h-5" role="img" aria-label="Stable traffic across 8 intervals"><i style="--v:55%" class="h-[var(--v)] rounded-[1px] bg-tgx05-ok/60"></i><i style="--v:62%" class="h-[var(--v)] rounded-[1px] bg-tgx05-ok/60"></i><i style="--v:58%" class="h-[var(--v)] rounded-[1px] bg-tgx05-ok/60"></i><i style="--v:70%" class="h-[var(--v)] rounded-[1px] bg-tgx05-ok/60"></i><i style="--v:66%" class="h-[var(--v)] rounded-[1px] bg-tgx05-ok/60"></i><i style="--v:74%" class="h-[var(--v)] rounded-[1px] bg-tgx05-ok/60"></i><i style="--v:69%" class="h-[var(--v)] rounded-[1px] bg-tgx05-ok/60"></i><i style="--v:78%" class="h-[var(--v)] rounded-[1px] bg-tgx05-ok"></i></span></span>
      <span role="cell" class="text-right tabular-nums text-tgx05-dim max-sm:hidden">1,204,118</span>
      <span role="cell" class="text-right tabular-nums text-tgx05-dim max-sm:hidden">184ms</span>
      <span role="cell" class="text-right tabular-nums text-tgx05-dim">0.02%</span>
      <span role="cell"><em class="not-italic text-[0.68rem] px-2 py-0.5 rounded-full border border-tgx05-ok/50 text-tgx05-ok bg-tgx05-ok/15">Healthy</em></span>
    </div>
    <div role="row" class="col-span-full [grid-template-columns:subgrid] grid items-center gap-x-4 px-4 py-3 border-t border-tgx05-line text-[0.84rem] transition-colors hover:bg-tgx05-hover">
      <span role="cell" class="flex flex-col"><span class="font-medium">auth-service</span><span class="text-[0.7rem] text-tgx05-dim">eu-west-1 · 6 pods</span></span>
      <span role="cell" class="max-sm:hidden"><span class="grid grid-cols-8 items-end gap-[2px] h-5" role="img" aria-label="Latency climbing across 8 intervals"><i style="--v:40%" class="h-[var(--v)] rounded-[1px] bg-tgx05-warn/60"></i><i style="--v:44%" class="h-[var(--v)] rounded-[1px] bg-tgx05-warn/60"></i><i style="--v:52%" class="h-[var(--v)] rounded-[1px] bg-tgx05-warn/60"></i><i style="--v:58%" class="h-[var(--v)] rounded-[1px] bg-tgx05-warn/60"></i><i style="--v:67%" class="h-[var(--v)] rounded-[1px] bg-tgx05-warn/60"></i><i style="--v:75%" class="h-[var(--v)] rounded-[1px] bg-tgx05-warn/60"></i><i style="--v:84%" class="h-[var(--v)] rounded-[1px] bg-tgx05-warn/60"></i><i style="--v:92%" class="h-[var(--v)] rounded-[1px] bg-tgx05-warn"></i></span></span>
      <span role="cell" class="text-right tabular-nums text-tgx05-dim max-sm:hidden">386,402</span>
      <span role="cell" class="text-right tabular-nums text-tgx05-warn max-sm:hidden">312ms</span>
      <span role="cell" class="text-right tabular-nums text-tgx05-dim">0.14%</span>
      <span role="cell"><em class="not-italic text-[0.68rem] px-2 py-0.5 rounded-full border border-tgx05-warn/50 text-tgx05-warn bg-tgx05-warn/15">Degraded</em></span>
    </div>
    <div role="row" class="col-span-full [grid-template-columns:subgrid] grid items-center gap-x-4 px-4 py-3 border-t border-tgx05-line text-[0.84rem] transition-colors hover:bg-tgx05-hover">
      <span role="cell" class="flex flex-col"><span class="font-medium">billing-worker</span><span class="text-[0.7rem] text-tgx05-dim">us-east-1 · 4 pods</span></span>
      <span role="cell" class="max-sm:hidden"><span class="grid grid-cols-8 items-end gap-[2px] h-5" role="img" aria-label="Flat, low traffic across 8 intervals"><i style="--v:30%" class="h-[var(--v)] rounded-[1px] bg-tgx05-ok/60"></i><i style="--v:34%" class="h-[var(--v)] rounded-[1px] bg-tgx05-ok/60"></i><i style="--v:31%" class="h-[var(--v)] rounded-[1px] bg-tgx05-ok/60"></i><i style="--v:38%" class="h-[var(--v)] rounded-[1px] bg-tgx05-ok/60"></i><i style="--v:35%" class="h-[var(--v)] rounded-[1px] bg-tgx05-ok/60"></i><i style="--v:40%" class="h-[var(--v)] rounded-[1px] bg-tgx05-ok/60"></i><i style="--v:37%" class="h-[var(--v)] rounded-[1px] bg-tgx05-ok/60"></i><i style="--v:42%" class="h-[var(--v)] rounded-[1px] bg-tgx05-ok"></i></span></span>
      <span role="cell" class="text-right tabular-nums text-tgx05-dim max-sm:hidden">92,377</span>
      <span role="cell" class="text-right tabular-nums text-tgx05-dim max-sm:hidden">96ms</span>
      <span role="cell" class="text-right tabular-nums text-tgx05-dim">0.00%</span>
      <span role="cell"><em class="not-italic text-[0.68rem] px-2 py-0.5 rounded-full border border-tgx05-ok/50 text-tgx05-ok bg-tgx05-ok/15">Healthy</em></span>
    </div>
    <div role="row" class="col-span-full [grid-template-columns:subgrid] grid items-center gap-x-4 px-4 py-3 border-t border-tgx05-line text-[0.84rem] transition-colors hover:bg-tgx05-hover">
      <span role="cell" class="flex flex-col"><span class="font-medium">search-indexer</span><span class="text-[0.7rem] text-tgx05-dim">us-east-1 · 2 pods</span></span>
      <span role="cell" class="max-sm:hidden"><span class="grid grid-cols-8 items-end gap-[2px] h-5" role="img" aria-label="Sharp drop in throughput over 8 intervals"><i style="--v:88%" class="h-[var(--v)] rounded-[1px] bg-tgx05-down/60"></i><i style="--v:80%" class="h-[var(--v)] rounded-[1px] bg-tgx05-down/60"></i><i style="--v:62%" class="h-[var(--v)] rounded-[1px] bg-tgx05-down/60"></i><i style="--v:48%" class="h-[var(--v)] rounded-[1px] bg-tgx05-down/60"></i><i style="--v:30%" class="h-[var(--v)] rounded-[1px] bg-tgx05-down/60"></i><i style="--v:22%" class="h-[var(--v)] rounded-[1px] bg-tgx05-down/60"></i><i style="--v:14%" class="h-[var(--v)] rounded-[1px] bg-tgx05-down/60"></i><i style="--v:9%" class="h-[var(--v)] rounded-[1px] bg-tgx05-down"></i></span></span>
      <span role="cell" class="text-right tabular-nums text-tgx05-dim max-sm:hidden">14,051</span>
      <span role="cell" class="text-right tabular-nums text-tgx05-down max-sm:hidden">1,240ms</span>
      <span role="cell" class="text-right tabular-nums text-tgx05-down">2.31%</span>
      <span role="cell"><em class="not-italic text-[0.68rem] px-2 py-0.5 rounded-full border border-tgx05-down/50 text-tgx05-down bg-tgx05-down/15">Failing</em></span>
    </div>
  </div>
</section>
@import "tailwindcss";

@theme {
  --color-tgx05-bg: #10161a;
  --color-tgx05-bg: oklch(0.17 0.015 210);
  --color-tgx05-panel: #151d22;
  --color-tgx05-panel: oklch(0.21 0.02 210);
  --color-tgx05-head: #1a242a;
  --color-tgx05-head: oklch(0.25 0.02 210);
  --color-tgx05-hover: #1d282f;
  --color-tgx05-hover: oklch(0.27 0.02 210);
  --color-tgx05-line: #31424a;
  --color-tgx05-line: oklch(0.36 0.025 210);
  --color-tgx05-ink: #e8f0f3;
  --color-tgx05-ink: oklch(0.94 0.01 210);
  --color-tgx05-dim: #a6b8bf;
  --color-tgx05-dim: oklch(0.76 0.015 210);
  --color-tgx05-ok: #7fe3b0;
  --color-tgx05-ok: oklch(0.85 0.14 155);
  --color-tgx05-warn: #f0cc72;
  --color-tgx05-warn: oklch(0.86 0.14 85);
  --color-tgx05-down: #f4998a;
  --color-tgx05-down: oklch(0.78 0.14 25);
  --font-tgx05-sans: 'Inter Tight', system-ui, sans-serif;
  --font-tgx05-mono: 'JetBrains Mono', ui-monospace, monospace;
}

.tgx-05 {
  width: 100%;
  min-height: 100svh;
}

@supports not (grid-template-columns: subgrid) {
  .tgx-05 [role="row"] {
    grid-template-columns: minmax(150px, 1.6fr) minmax(86px, 0.8fr) minmax(80px, 0.7fr) minmax(80px, 0.7fr) minmax(90px, 0.8fr) minmax(84px, max-content);
  }
}

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-tgx05-bg: #10161a;
  --color-tgx05-bg: oklch(0.17 0.015 210);
  --color-tgx05-panel: #151d22;
  --color-tgx05-panel: oklch(0.21 0.02 210);
  --color-tgx05-head: #1a242a;
  --color-tgx05-head: oklch(0.25 0.02 210);
  --color-tgx05-hover: #1d282f;
  --color-tgx05-hover: oklch(0.27 0.02 210);
  --color-tgx05-line: #31424a;
  --color-tgx05-line: oklch(0.36 0.025 210);
  --color-tgx05-ink: #e8f0f3;
  --color-tgx05-ink: oklch(0.94 0.01 210);
  --color-tgx05-dim: #a6b8bf;
  --color-tgx05-dim: oklch(0.76 0.015 210);
  --color-tgx05-ok: #7fe3b0;
  --color-tgx05-ok: oklch(0.85 0.14 155);
  --color-tgx05-warn: #f0cc72;
  --color-tgx05-warn: oklch(0.86 0.14 85);
  --color-tgx05-down: #f4998a;
  --color-tgx05-down: oklch(0.78 0.14 25);
  --font-tgx05-sans: 'Inter Tight', system-ui, sans-serif;
  --font-tgx05-mono: 'JetBrains Mono', ui-monospace, monospace;
}

.tgx-05 {
  width: 100%;
  min-height: 100svh;
}

@supports not (grid-template-columns: subgrid) {
  .tgx-05 [role="row"] {
    grid-template-columns: minmax(150px, 1.6fr) minmax(86px, 0.8fr) minmax(80px, 0.7fr) minmax(80px, 0.7fr) minmax(90px, 0.8fr) minmax(84px, max-content);
  }
}
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=Inter+Tight:wght@400;500;600&family=JetBrains+Mono:wght@400;500&display=swap">

What changed in the port

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

  • The sparkline column is what makes subgrid earn its place: an eight-bar mini-grid inside a subgrid cell, still aligned to the parent's track, with no width juggling.
  • Each service now carries a region and pod count on a second line — and because the rows are subgrid, that taller first cell does not break alignment anywhere else.
  • Product upgrade: a flat five-column list became a real console view with a header summary, per-row trend sparklines, latency units and colour-coded failing figures; col-span-full still does the structural work.
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 Data Table with Subgrid Rows and Status Pills
Source: https://codefronts.com/layouts/tailwind-css-grid-layouts/tailwind-data-table-subgrid-rows-status-pills/

A service-health table from an observability console: sparkline per service, tabular figures that line up by digit, status pills that never squash, and one master track list every row inherits with [grid-template-columns:subgrid].
## HTML
```html
<section class="tgx-05 w-full min-h-svh bg-tgx05-bg font-tgx05-sans text-tgx05-ink p-6">
  <header class="flex items-end justify-between gap-4 flex-wrap mb-4">
    <div class="flex flex-col gap-1">
      <p class="font-tgx05-mono text-[0.68rem] tracking-[0.1em] uppercase text-tgx05-dim">Vantage · Observability</p>
      <h2 class="text-[1.25rem] font-semibold tracking-[-0.01em]">Service health — last 24h</h2>
    </div>
    <div class="flex items-center gap-2 text-[0.72rem] text-tgx05-dim">
      <span class="inline-flex items-center gap-1.5 rounded-full border border-tgx05-line px-2.5 py-1"><span class="size-1.5 rounded-full bg-tgx05-ok"></span>3 healthy</span>
      <span class="inline-flex items-center gap-1.5 rounded-full border border-tgx05-line px-2.5 py-1"><span class="size-1.5 rounded-full bg-tgx05-down"></span>1 failing</span>
    </div>
  </header>
  <div role="table" aria-label="Service health" class="grid grid-cols-[minmax(150px,1.6fr)_minmax(86px,0.8fr)_minmax(80px,0.7fr)_minmax(80px,0.7fr)_minmax(90px,0.8fr)_minmax(84px,max-content)] max-sm:grid-cols-[minmax(120px,1.6fr)_minmax(80px,1fr)_minmax(84px,max-content)] rounded-xl border border-tgx05-line overflow-hidden bg-tgx05-panel">
    <div role="row" class="col-span-full [grid-template-columns:subgrid] grid items-center gap-x-4 px-4 py-2.5 bg-tgx05-head text-[0.66rem] tracking-[0.12em] uppercase text-tgx05-dim">
      <span role="columnheader">Service</span>
      <span role="columnheader" class="max-sm:hidden">Trend</span>
      <span role="columnheader" class="text-right max-sm:hidden">Requests</span>
      <span role="columnheader" class="text-right max-sm:hidden">p95</span>
      <span role="columnheader" class="text-right">Errors</span>
      <span role="columnheader">Status</span>
    </div>
    <div role="row" class="col-span-full [grid-template-columns:subgrid] grid items-center gap-x-4 px-4 py-3 border-t border-tgx05-line text-[0.84rem] transition-colors hover:bg-tgx05-hover">
      <span role="cell" class="flex flex-col"><span class="font-medium">edge-gateway</span><span class="text-[0.7rem] text-tgx05-dim">eu-west-1 · 12 pods</span></span>
      <span role="cell" class="max-sm:hidden"><span class="grid grid-cols-8 items-end gap-[2px] h-5" role="img" aria-label="Stable traffic across 8 intervals"><i style="--v:55%" class="h-[var(--v)] rounded-[1px] bg-tgx05-ok/60"></i><i style="--v:62%" class="h-[var(--v)] rounded-[1px] bg-tgx05-ok/60"></i><i style="--v:58%" class="h-[var(--v)] rounded-[1px] bg-tgx05-ok/60"></i><i style="--v:70%" class="h-[var(--v)] rounded-[1px] bg-tgx05-ok/60"></i><i style="--v:66%" class="h-[var(--v)] rounded-[1px] bg-tgx05-ok/60"></i><i style="--v:74%" class="h-[var(--v)] rounded-[1px] bg-tgx05-ok/60"></i><i style="--v:69%" class="h-[var(--v)] rounded-[1px] bg-tgx05-ok/60"></i><i style="--v:78%" class="h-[var(--v)] rounded-[1px] bg-tgx05-ok"></i></span></span>
      <span role="cell" class="text-right tabular-nums text-tgx05-dim max-sm:hidden">1,204,118</span>
      <span role="cell" class="text-right tabular-nums text-tgx05-dim max-sm:hidden">184ms</span>
      <span role="cell" class="text-right tabular-nums text-tgx05-dim">0.02%</span>
      <span role="cell"><em class="not-italic text-[0.68rem] px-2 py-0.5 rounded-full border border-tgx05-ok/50 text-tgx05-ok bg-tgx05-ok/15">Healthy</em></span>
    </div>
    <div role="row" class="col-span-full [grid-template-columns:subgrid] grid items-center gap-x-4 px-4 py-3 border-t border-tgx05-line text-[0.84rem] transition-colors hover:bg-tgx05-hover">
      <span role="cell" class="flex flex-col"><span class="font-medium">auth-service</span><span class="text-[0.7rem] text-tgx05-dim">eu-west-1 · 6 pods</span></span>
      <span role="cell" class="max-sm:hidden"><span class="grid grid-cols-8 items-end gap-[2px] h-5" role="img" aria-label="Latency climbing across 8 intervals"><i style="--v:40%" class="h-[var(--v)] rounded-[1px] bg-tgx05-warn/60"></i><i style="--v:44%" class="h-[var(--v)] rounded-[1px] bg-tgx05-warn/60"></i><i style="--v:52%" class="h-[var(--v)] rounded-[1px] bg-tgx05-warn/60"></i><i style="--v:58%" class="h-[var(--v)] rounded-[1px] bg-tgx05-warn/60"></i><i style="--v:67%" class="h-[var(--v)] rounded-[1px] bg-tgx05-warn/60"></i><i style="--v:75%" class="h-[var(--v)] rounded-[1px] bg-tgx05-warn/60"></i><i style="--v:84%" class="h-[var(--v)] rounded-[1px] bg-tgx05-warn/60"></i><i style="--v:92%" class="h-[var(--v)] rounded-[1px] bg-tgx05-warn"></i></span></span>
      <span role="cell" class="text-right tabular-nums text-tgx05-dim max-sm:hidden">386,402</span>
      <span role="cell" class="text-right tabular-nums text-tgx05-warn max-sm:hidden">312ms</span>
      <span role="cell" class="text-right tabular-nums text-tgx05-dim">0.14%</span>
      <span role="cell"><em class="not-italic text-[0.68rem] px-2 py-0.5 rounded-full border border-tgx05-warn/50 text-tgx05-warn bg-tgx05-warn/15">Degraded</em></span>
    </div>
    <div role="row" class="col-span-full [grid-template-columns:subgrid] grid items-center gap-x-4 px-4 py-3 border-t border-tgx05-line text-[0.84rem] transition-colors hover:bg-tgx05-hover">
      <span role="cell" class="flex flex-col"><span class="font-medium">billing-worker</span><span class="text-[0.7rem] text-tgx05-dim">us-east-1 · 4 pods</span></span>
      <span role="cell" class="max-sm:hidden"><span class="grid grid-cols-8 items-end gap-[2px] h-5" role="img" aria-label="Flat, low traffic across 8 intervals"><i style="--v:30%" class="h-[var(--v)] rounded-[1px] bg-tgx05-ok/60"></i><i style="--v:34%" class="h-[var(--v)] rounded-[1px] bg-tgx05-ok/60"></i><i style="--v:31%" class="h-[var(--v)] rounded-[1px] bg-tgx05-ok/60"></i><i style="--v:38%" class="h-[var(--v)] rounded-[1px] bg-tgx05-ok/60"></i><i style="--v:35%" class="h-[var(--v)] rounded-[1px] bg-tgx05-ok/60"></i><i style="--v:40%" class="h-[var(--v)] rounded-[1px] bg-tgx05-ok/60"></i><i style="--v:37%" class="h-[var(--v)] rounded-[1px] bg-tgx05-ok/60"></i><i style="--v:42%" class="h-[var(--v)] rounded-[1px] bg-tgx05-ok"></i></span></span>
      <span role="cell" class="text-right tabular-nums text-tgx05-dim max-sm:hidden">92,377</span>
      <span role="cell" class="text-right tabular-nums text-tgx05-dim max-sm:hidden">96ms</span>
      <span role="cell" class="text-right tabular-nums text-tgx05-dim">0.00%</span>
      <span role="cell"><em class="not-italic text-[0.68rem] px-2 py-0.5 rounded-full border border-tgx05-ok/50 text-tgx05-ok bg-tgx05-ok/15">Healthy</em></span>
    </div>
    <div role="row" class="col-span-full [grid-template-columns:subgrid] grid items-center gap-x-4 px-4 py-3 border-t border-tgx05-line text-[0.84rem] transition-colors hover:bg-tgx05-hover">
      <span role="cell" class="flex flex-col"><span class="font-medium">search-indexer</span><span class="text-[0.7rem] text-tgx05-dim">us-east-1 · 2 pods</span></span>
      <span role="cell" class="max-sm:hidden"><span class="grid grid-cols-8 items-end gap-[2px] h-5" role="img" aria-label="Sharp drop in throughput over 8 intervals"><i style="--v:88%" class="h-[var(--v)] rounded-[1px] bg-tgx05-down/60"></i><i style="--v:80%" class="h-[var(--v)] rounded-[1px] bg-tgx05-down/60"></i><i style="--v:62%" class="h-[var(--v)] rounded-[1px] bg-tgx05-down/60"></i><i style="--v:48%" class="h-[var(--v)] rounded-[1px] bg-tgx05-down/60"></i><i style="--v:30%" class="h-[var(--v)] rounded-[1px] bg-tgx05-down/60"></i><i style="--v:22%" class="h-[var(--v)] rounded-[1px] bg-tgx05-down/60"></i><i style="--v:14%" class="h-[var(--v)] rounded-[1px] bg-tgx05-down/60"></i><i style="--v:9%" class="h-[var(--v)] rounded-[1px] bg-tgx05-down"></i></span></span>
      <span role="cell" class="text-right tabular-nums text-tgx05-dim max-sm:hidden">14,051</span>
      <span role="cell" class="text-right tabular-nums text-tgx05-down max-sm:hidden">1,240ms</span>
      <span role="cell" class="text-right tabular-nums text-tgx05-down">2.31%</span>
      <span role="cell"><em class="not-italic text-[0.68rem] px-2 py-0.5 rounded-full border border-tgx05-down/50 text-tgx05-down bg-tgx05-down/15">Failing</em></span>
    </div>
  </div>
</section>
```
## CSS
```css
@import "tailwindcss";

@theme {
  --color-tgx05-bg: #10161a;
  --color-tgx05-bg: oklch(0.17 0.015 210);
  --color-tgx05-panel: #151d22;
  --color-tgx05-panel: oklch(0.21 0.02 210);
  --color-tgx05-head: #1a242a;
  --color-tgx05-head: oklch(0.25 0.02 210);
  --color-tgx05-hover: #1d282f;
  --color-tgx05-hover: oklch(0.27 0.02 210);
  --color-tgx05-line: #31424a;
  --color-tgx05-line: oklch(0.36 0.025 210);
  --color-tgx05-ink: #e8f0f3;
  --color-tgx05-ink: oklch(0.94 0.01 210);
  --color-tgx05-dim: #a6b8bf;
  --color-tgx05-dim: oklch(0.76 0.015 210);
  --color-tgx05-ok: #7fe3b0;
  --color-tgx05-ok: oklch(0.85 0.14 155);
  --color-tgx05-warn: #f0cc72;
  --color-tgx05-warn: oklch(0.86 0.14 85);
  --color-tgx05-down: #f4998a;
  --color-tgx05-down: oklch(0.78 0.14 25);
  --font-tgx05-sans: 'Inter Tight', system-ui, sans-serif;
  --font-tgx05-mono: 'JetBrains Mono', ui-monospace, monospace;
}

.tgx-05 {
  width: 100%;
  min-height: 100svh;
}

@supports not (grid-template-columns: subgrid) {
  .tgx-05 [role="row"] {
    grid-template-columns: minmax(150px, 1.6fr) minmax(86px, 0.8fr) minmax(80px, 0.7fr) minmax(80px, 0.7fr) minmax(90px, 0.8fr) minmax(84px, max-content);
  }
}
```

How this works

Rows own no track list. They span the parent's full range, then adopt it. Change the master list once and forty rows follow — the reason this beats repeating a grid template per row.

The pill column is max-content, so 'Degraded' and 'Healthy' set their own width and never wrap mid-word, while the service column takes the slack.

Make it yours

  • Add a column by extending the ONE track list and adding a cell per row.
  • Zebra rows: odd:bg-tgx05-zebra on the row — one variant, no :nth-child rule.
  • Sortable headers: wrap each label in a button and add aria-sort; the layout is unaffected.

Gotchas — read before shipping

  • Rows need col-span-full before subgrid inherits anything.
  • For real table semantics (sorting, screen-reader table nav), keep a native <table> and grid the tr.
  • max-content columns never shrink — pills and icons only, never prose.

Browser support

ChromeSafariFirefoxEdge
117+16+128+117+

subgrid is Baseline 2023; the @supports block repeats the track list per row for older engines.

Techniques used in this demo

Search CodeFronts

Loading…