30 Tailwind CSS Grid Layouts
09 / 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 Bento Grid for a Product Feature Section

The feature section every modern product page ships: a 2×2 hero tile with real numbers, a photo tile, a metric tile and satellites — each with its own accent driven by a single inline custom property.

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-09 w-full min-h-svh bg-tgx09-bg font-tgx09-sans p-6">
  <header class="flex flex-col gap-1.5 mb-5">
    <p class="font-tgx09-mono text-[0.66rem] tracking-[0.18em] uppercase text-tgx09-dim">Lumen 3.0</p>
    <h2 class="text-[1.5rem] font-semibold tracking-[-0.015em] text-white">Everything your team watches, on one board</h2>
  </header>
  <div class="grid grid-cols-4 max-sm:grid-cols-2 auto-rows-[minmax(104px,auto)] gap-3">
    <article style="--glow:oklch(0.78 0.16 300)" class="col-span-2 row-span-2 max-sm:col-span-2 flex flex-col justify-between gap-4 rounded-2xl p-5 bg-tgx09-tile bg-[image:radial-gradient(140%_120%_at_15%_0%,color-mix(in_oklab,var(--glow)_18%,transparent),transparent_58%)] border border-[color-mix(in_oklab,var(--glow)_30%,oklch(0.32_0.02_290))] transition duration-200 hover:-translate-y-1 hover:shadow-[0_18px_36px_-18px_color-mix(in_oklab,var(--glow)_45%,transparent)] motion-reduce:transition-none motion-reduce:hover:translate-y-0">
      <div class="flex flex-col gap-2">
        <h3 class="text-[clamp(1.2rem,2.6vw,1.6rem)] leading-[1.15] font-semibold text-[var(--glow)]">Real-time pipeline health</h3>
        <p class="text-[0.85rem] leading-[1.55] text-tgx09-dim max-w-[36ch]">Every deploy, queue and worker in one view, updated as events land — no refresh, no polling loop of your own.</p>
      </div>
      <dl class="grid grid-cols-3 gap-3 pt-3 border-t border-white/10">
        <div><dt class="text-[0.6rem] uppercase tracking-[0.1em] text-tgx09-dim">Events/s</dt><dd class="text-[1.1rem] font-semibold tabular-nums text-white">48k</dd></div>
        <div><dt class="text-[0.6rem] uppercase tracking-[0.1em] text-tgx09-dim">p99</dt><dd class="text-[1.1rem] font-semibold tabular-nums text-white">62ms</dd></div>
        <div><dt class="text-[0.6rem] uppercase tracking-[0.1em] text-tgx09-dim">Uptime</dt><dd class="text-[1.1rem] font-semibold tabular-nums text-white">99.99%</dd></div>
      </dl>
    </article>
    <article style="--glow:oklch(0.85 0.16 140)" class="flex flex-col justify-end gap-1.5 rounded-2xl p-4 bg-tgx09-tile bg-[image:radial-gradient(140%_120%_at_15%_0%,color-mix(in_oklab,var(--glow)_18%,transparent),transparent_58%)] border border-[color-mix(in_oklab,var(--glow)_30%,oklch(0.32_0.02_290))] transition duration-200 hover:-translate-y-1 motion-reduce:transition-none motion-reduce:hover:translate-y-0">
      <p class="text-[1.6rem] font-semibold tabular-nums leading-none text-[var(--glow)]">−41%</p>
      <h4 class="text-[0.86rem] font-medium text-white">Mean time to detect</h4>
      <p class="text-[0.74rem] leading-[1.45] text-tgx09-dim">After switching alerts to streams.</p>
    </article>
    <article style="--glow:oklch(0.82 0.14 200)" class="row-span-2 overflow-hidden flex flex-col rounded-2xl bg-tgx09-tile border border-[color-mix(in_oklab,var(--glow)_30%,oklch(0.32_0.02_290))] transition duration-200 hover:-translate-y-1 motion-reduce:transition-none motion-reduce:hover:translate-y-0">
      <div class="aspect-[4/3] overflow-hidden"><img src="https://images.unsplash.com/photo-1498050108023-c5249f4df085?w=600&h=450&q=80&auto=format&fit=crop" alt="Developer workstation with a code editor open on screen" loading="lazy" class="w-full h-full object-cover"></div>
      <div class="flex flex-col gap-1.5 p-4">
        <h4 class="text-[0.9rem] font-semibold text-[var(--glow)]">Built for the terminal crowd</h4>
        <p class="text-[0.76rem] leading-[1.5] text-tgx09-dim">Every board has a CLI equivalent and a stable JSON export.</p>
      </div>
    </article>
    <article style="--glow:oklch(0.8 0.15 60)" class="col-span-2 flex items-center justify-between gap-4 rounded-2xl p-4 bg-tgx09-tile bg-[image:radial-gradient(140%_120%_at_15%_0%,color-mix(in_oklab,var(--glow)_18%,transparent),transparent_58%)] border border-[color-mix(in_oklab,var(--glow)_30%,oklch(0.32_0.02_290))] transition duration-200 hover:-translate-y-1 motion-reduce:transition-none motion-reduce:hover:translate-y-0">
      <div class="flex flex-col gap-1">
        <h4 class="text-[0.9rem] font-semibold text-[var(--glow)]">Traffic, last 12 hours</h4>
        <p class="text-[0.74rem] text-tgx09-dim">Steady climb after the 14:00 release.</p>
      </div>
      <div role="img" aria-label="Bar chart rising across 10 intervals" class="grid grid-cols-10 items-end gap-[3px] h-12 w-[45%] min-w-[120px]">
        <i style="--v:32%" class="h-[var(--v)] rounded-t-[2px] bg-[var(--glow)]/70"></i><i style="--v:44%" class="h-[var(--v)] rounded-t-[2px] bg-[var(--glow)]/70"></i><i style="--v:38%" class="h-[var(--v)] rounded-t-[2px] bg-[var(--glow)]/70"></i><i style="--v:56%" class="h-[var(--v)] rounded-t-[2px] bg-[var(--glow)]/70"></i><i style="--v:62%" class="h-[var(--v)] rounded-t-[2px] bg-[var(--glow)]/70"></i><i style="--v:58%" class="h-[var(--v)] rounded-t-[2px] bg-[var(--glow)]/70"></i><i style="--v:74%" class="h-[var(--v)] rounded-t-[2px] bg-[var(--glow)]/70"></i><i style="--v:80%" class="h-[var(--v)] rounded-t-[2px] bg-[var(--glow)]/70"></i><i style="--v:88%" class="h-[var(--v)] rounded-t-[2px] bg-[var(--glow)]/85"></i><i style="--v:96%" class="h-[var(--v)] rounded-t-[2px] bg-[var(--glow)]"></i>
      </div>
    </article>
    <article style="--glow:oklch(0.78 0.13 250)" class="flex flex-col justify-end gap-1.5 rounded-2xl p-4 bg-tgx09-tile bg-[image:radial-gradient(140%_120%_at_15%_0%,color-mix(in_oklab,var(--glow)_18%,transparent),transparent_58%)] border border-[color-mix(in_oklab,var(--glow)_30%,oklch(0.32_0.02_290))] transition duration-200 hover:-translate-y-1 motion-reduce:transition-none motion-reduce:hover:translate-y-0">
      <h4 class="text-[0.9rem] font-semibold text-[var(--glow)]">SOC 2 Type II</h4>
      <p class="text-[0.74rem] leading-[1.45] text-tgx09-dim">Audited annually. Logs stay in your region.</p>
    </article>
  </div>
</section>
@import "tailwindcss";

@theme {
  --color-tgx09-bg: #17141f;
  --color-tgx09-bg: oklch(0.16 0.015 290);
  --color-tgx09-tile: #241f31;
  --color-tgx09-tile: oklch(0.22 0.02 290);
  --color-tgx09-dim: #b3aec2;
  --color-tgx09-dim: oklch(0.76 0.02 290);
  --font-tgx09-sans: 'Inter Tight', system-ui, sans-serif;
  --font-tgx09-mono: 'JetBrains Mono', ui-monospace, monospace;
}

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

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-tgx09-bg: #17141f;
  --color-tgx09-bg: oklch(0.16 0.015 290);
  --color-tgx09-tile: #241f31;
  --color-tgx09-tile: oklch(0.22 0.02 290);
  --color-tgx09-dim: #b3aec2;
  --color-tgx09-dim: oklch(0.76 0.02 290);
  --font-tgx09-sans: 'Inter Tight', system-ui, sans-serif;
  --font-tgx09-mono: 'JetBrains Mono', ui-monospace, monospace;
}

.tgx-09 {
  width: 100%;
  min-height: 100svh;
}
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="preconnect" href="https://images.unsplash.com">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter+Tight:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap">

What changed in the port

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

  • Six tiles, six different content shapes — a stat block, a photo, a chart, a compliance note — all held by the same span vocabulary. That variety is the argument for bento over a card row.
  • The photo tile puts the image in a ratio'd wrapper and lets the text block size itself, so a row-span-2 tile never stretches the picture.
  • Product upgrade: tiles that described the grid now describe a product, with real figures, a screenshot, an inline bar chart and a security line — and the background split into bg-[image:…] + a token so the wash actually compiles.
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 Bento Grid for a Product Feature Section
Source: https://codefronts.com/layouts/tailwind-css-grid-layouts/tailwind-bento-grid-product-feature-section/

The feature section every modern product page ships: a 2×2 hero tile with real numbers, a photo tile, a metric tile and satellites — each with its own accent driven by a single inline custom property.
## HTML
```html
<section class="tgx-09 w-full min-h-svh bg-tgx09-bg font-tgx09-sans p-6">
  <header class="flex flex-col gap-1.5 mb-5">
    <p class="font-tgx09-mono text-[0.66rem] tracking-[0.18em] uppercase text-tgx09-dim">Lumen 3.0</p>
    <h2 class="text-[1.5rem] font-semibold tracking-[-0.015em] text-white">Everything your team watches, on one board</h2>
  </header>
  <div class="grid grid-cols-4 max-sm:grid-cols-2 auto-rows-[minmax(104px,auto)] gap-3">
    <article style="--glow:oklch(0.78 0.16 300)" class="col-span-2 row-span-2 max-sm:col-span-2 flex flex-col justify-between gap-4 rounded-2xl p-5 bg-tgx09-tile bg-[image:radial-gradient(140%_120%_at_15%_0%,color-mix(in_oklab,var(--glow)_18%,transparent),transparent_58%)] border border-[color-mix(in_oklab,var(--glow)_30%,oklch(0.32_0.02_290))] transition duration-200 hover:-translate-y-1 hover:shadow-[0_18px_36px_-18px_color-mix(in_oklab,var(--glow)_45%,transparent)] motion-reduce:transition-none motion-reduce:hover:translate-y-0">
      <div class="flex flex-col gap-2">
        <h3 class="text-[clamp(1.2rem,2.6vw,1.6rem)] leading-[1.15] font-semibold text-[var(--glow)]">Real-time pipeline health</h3>
        <p class="text-[0.85rem] leading-[1.55] text-tgx09-dim max-w-[36ch]">Every deploy, queue and worker in one view, updated as events land — no refresh, no polling loop of your own.</p>
      </div>
      <dl class="grid grid-cols-3 gap-3 pt-3 border-t border-white/10">
        <div><dt class="text-[0.6rem] uppercase tracking-[0.1em] text-tgx09-dim">Events/s</dt><dd class="text-[1.1rem] font-semibold tabular-nums text-white">48k</dd></div>
        <div><dt class="text-[0.6rem] uppercase tracking-[0.1em] text-tgx09-dim">p99</dt><dd class="text-[1.1rem] font-semibold tabular-nums text-white">62ms</dd></div>
        <div><dt class="text-[0.6rem] uppercase tracking-[0.1em] text-tgx09-dim">Uptime</dt><dd class="text-[1.1rem] font-semibold tabular-nums text-white">99.99%</dd></div>
      </dl>
    </article>
    <article style="--glow:oklch(0.85 0.16 140)" class="flex flex-col justify-end gap-1.5 rounded-2xl p-4 bg-tgx09-tile bg-[image:radial-gradient(140%_120%_at_15%_0%,color-mix(in_oklab,var(--glow)_18%,transparent),transparent_58%)] border border-[color-mix(in_oklab,var(--glow)_30%,oklch(0.32_0.02_290))] transition duration-200 hover:-translate-y-1 motion-reduce:transition-none motion-reduce:hover:translate-y-0">
      <p class="text-[1.6rem] font-semibold tabular-nums leading-none text-[var(--glow)]">−41%</p>
      <h4 class="text-[0.86rem] font-medium text-white">Mean time to detect</h4>
      <p class="text-[0.74rem] leading-[1.45] text-tgx09-dim">After switching alerts to streams.</p>
    </article>
    <article style="--glow:oklch(0.82 0.14 200)" class="row-span-2 overflow-hidden flex flex-col rounded-2xl bg-tgx09-tile border border-[color-mix(in_oklab,var(--glow)_30%,oklch(0.32_0.02_290))] transition duration-200 hover:-translate-y-1 motion-reduce:transition-none motion-reduce:hover:translate-y-0">
      <div class="aspect-[4/3] overflow-hidden"><img src="https://images.unsplash.com/photo-1498050108023-c5249f4df085?w=600&h=450&q=80&auto=format&fit=crop" alt="Developer workstation with a code editor open on screen" loading="lazy" class="w-full h-full object-cover"></div>
      <div class="flex flex-col gap-1.5 p-4">
        <h4 class="text-[0.9rem] font-semibold text-[var(--glow)]">Built for the terminal crowd</h4>
        <p class="text-[0.76rem] leading-[1.5] text-tgx09-dim">Every board has a CLI equivalent and a stable JSON export.</p>
      </div>
    </article>
    <article style="--glow:oklch(0.8 0.15 60)" class="col-span-2 flex items-center justify-between gap-4 rounded-2xl p-4 bg-tgx09-tile bg-[image:radial-gradient(140%_120%_at_15%_0%,color-mix(in_oklab,var(--glow)_18%,transparent),transparent_58%)] border border-[color-mix(in_oklab,var(--glow)_30%,oklch(0.32_0.02_290))] transition duration-200 hover:-translate-y-1 motion-reduce:transition-none motion-reduce:hover:translate-y-0">
      <div class="flex flex-col gap-1">
        <h4 class="text-[0.9rem] font-semibold text-[var(--glow)]">Traffic, last 12 hours</h4>
        <p class="text-[0.74rem] text-tgx09-dim">Steady climb after the 14:00 release.</p>
      </div>
      <div role="img" aria-label="Bar chart rising across 10 intervals" class="grid grid-cols-10 items-end gap-[3px] h-12 w-[45%] min-w-[120px]">
        <i style="--v:32%" class="h-[var(--v)] rounded-t-[2px] bg-[var(--glow)]/70"></i><i style="--v:44%" class="h-[var(--v)] rounded-t-[2px] bg-[var(--glow)]/70"></i><i style="--v:38%" class="h-[var(--v)] rounded-t-[2px] bg-[var(--glow)]/70"></i><i style="--v:56%" class="h-[var(--v)] rounded-t-[2px] bg-[var(--glow)]/70"></i><i style="--v:62%" class="h-[var(--v)] rounded-t-[2px] bg-[var(--glow)]/70"></i><i style="--v:58%" class="h-[var(--v)] rounded-t-[2px] bg-[var(--glow)]/70"></i><i style="--v:74%" class="h-[var(--v)] rounded-t-[2px] bg-[var(--glow)]/70"></i><i style="--v:80%" class="h-[var(--v)] rounded-t-[2px] bg-[var(--glow)]/70"></i><i style="--v:88%" class="h-[var(--v)] rounded-t-[2px] bg-[var(--glow)]/85"></i><i style="--v:96%" class="h-[var(--v)] rounded-t-[2px] bg-[var(--glow)]"></i>
      </div>
    </article>
    <article style="--glow:oklch(0.78 0.13 250)" class="flex flex-col justify-end gap-1.5 rounded-2xl p-4 bg-tgx09-tile bg-[image:radial-gradient(140%_120%_at_15%_0%,color-mix(in_oklab,var(--glow)_18%,transparent),transparent_58%)] border border-[color-mix(in_oklab,var(--glow)_30%,oklch(0.32_0.02_290))] transition duration-200 hover:-translate-y-1 motion-reduce:transition-none motion-reduce:hover:translate-y-0">
      <h4 class="text-[0.9rem] font-semibold text-[var(--glow)]">SOC 2 Type II</h4>
      <p class="text-[0.74rem] leading-[1.45] text-tgx09-dim">Audited annually. Logs stay in your region.</p>
    </article>
  </div>
</section>
```
## CSS
```css
@import "tailwindcss";

@theme {
  --color-tgx09-bg: #17141f;
  --color-tgx09-bg: oklch(0.16 0.015 290);
  --color-tgx09-tile: #241f31;
  --color-tgx09-tile: oklch(0.22 0.02 290);
  --color-tgx09-dim: #b3aec2;
  --color-tgx09-dim: oklch(0.76 0.02 290);
  --font-tgx09-sans: 'Inter Tight', system-ui, sans-serif;
  --font-tgx09-mono: 'JetBrains Mono', ui-monospace, monospace;
}

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

How this works

Spans are the layout. Four columns, auto rows, and every tile states its footprint where you can see it — so re-arranging the bento is editing two numbers, not a stylesheet.

Per-tile theming stays a variable. A @theme entry per tile would mint six palettes for six one-off values; --glow is per-instance data and belongs inline, which is also exactly what a CMS writes.

Make it yours

  • Re-anchor the hero with explicit lines (col-start-3 col-end-5).
  • Add tiles freely; auto-placement fills the board, and grid-flow-dense closes holes.
  • Denser board: auto-rows-[minmax(88px,auto)].

Gotchas — read before shipping

  • Keep glow washes under ~20% alpha or tiles turn into neon signs.
  • Mobile must shrink spans too, or a span-2 tile forces horizontal scroll on a 2-column board.
  • In v4, a single bg-[…] cannot mix gradient layers with a trailing bare colour — use bg-[image:…] plus a colour utility.

Browser support

ChromeSafariFirefoxEdge
111+16.4+128+111+

oklch + color-mix theming (2023 evergreens); span geometry runs anywhere.

Techniques used in this demo

Utilitiesfirst-class utility or variant

Theme tokensset in @theme, used by a utility

Search CodeFronts

Loading…