30 Tailwind CSS Grid Layouts
15 / 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 Subgrid Cards with Perfectly Aligned Buttons

A template gallery where titles run to different lengths and descriptions to different depths — yet every badge, title, body and button sits on a shared line, because each card adopts the parent's row tracks. Flexbox's mt-auto workaround retires here.

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-15 w-full min-h-svh bg-tgx15-bg font-tgx15-sans p-6">
  <header class="flex items-end justify-between gap-4 flex-wrap mb-5">
    <div class="flex flex-col gap-1">
      <p class="text-[0.66rem] tracking-[0.18em] uppercase text-tgx15-mint">Relay · Templates</p>
      <h2 class="text-[1.35rem] font-semibold text-white tracking-[-0.01em]">Start from a workflow</h2>
    </div>
    <p class="text-[0.76rem] text-tgx15-dim">Every card spans the same four rows</p>
  </header>
  <div class="grid grid-cols-[repeat(auto-fit,minmax(min(210px,100%),1fr))] auto-rows-auto gap-4">
    <article class="row-span-4 [grid-template-rows:subgrid] grid gap-y-3 rounded-2xl border border-tgx15-edge bg-tgx15-card p-5">
      <p class="text-[0.64rem] tracking-[0.16em] uppercase text-tgx15-mint">Incident response</p>
      <h3 class="text-[1.05rem] leading-[1.3] font-semibold text-white text-balance">On-call triage</h3>
      <p class="text-[0.8rem] leading-[1.6] text-tgx15-dim">Route, acknowledge, escalate. Four steps, one channel.</p>
      <a href="#0" class="self-end justify-self-start inline-flex items-center min-h-11 px-4 rounded-full text-[0.82rem] font-semibold no-underline text-tgx15-ink bg-tgx15-mint transition-colors hover:bg-tgx15-minthover focus-visible:outline-2 focus-visible:outline-tgx15-mint focus-visible:outline-offset-[3px]">Use template</a>
    </article>
    <article class="row-span-4 [grid-template-rows:subgrid] grid gap-y-3 rounded-2xl border border-tgx15-mint bg-tgx15-cardhot p-5">
      <p class="text-[0.64rem] tracking-[0.16em] uppercase text-tgx15-mint">Release · most used</p>
      <h3 class="text-[1.05rem] leading-[1.3] font-semibold text-white text-balance">Progressive rollout with automatic rollback gates</h3>
      <p class="text-[0.8rem] leading-[1.6] text-tgx15-dim">Ship to 5%, watch error budget, promote or revert automatically. The long title above raises the title track for every sibling card — that is subgrid doing its job.</p>
      <a href="#0" class="self-end justify-self-start inline-flex items-center min-h-11 px-4 rounded-full text-[0.82rem] font-semibold no-underline text-tgx15-ink bg-tgx15-mint transition-colors hover:bg-tgx15-minthover focus-visible:outline-2 focus-visible:outline-tgx15-mint focus-visible:outline-offset-[3px]">Use template</a>
    </article>
    <article class="row-span-4 [grid-template-rows:subgrid] grid gap-y-3 rounded-2xl border border-tgx15-edge bg-tgx15-card p-5">
      <p class="text-[0.64rem] tracking-[0.16em] uppercase text-tgx15-mint">Reporting</p>
      <h3 class="text-[1.05rem] leading-[1.3] font-semibold text-white text-balance">Weekly digest</h3>
      <p class="text-[0.8rem] leading-[1.6] text-tgx15-dim">Short title, short copy — and the button still lands level with its neighbours, because the final track is shared rather than pushed down by content.</p>
      <a href="#0" class="self-end justify-self-start inline-flex items-center min-h-11 px-4 rounded-full text-[0.82rem] font-semibold no-underline text-tgx15-ink bg-tgx15-mint transition-colors hover:bg-tgx15-minthover focus-visible:outline-2 focus-visible:outline-tgx15-mint focus-visible:outline-offset-[3px]">Use template</a>
    </article>
  </div>
</section>
@import "tailwindcss";

@theme {
  --color-tgx15-bg: #1a2724;
  --color-tgx15-bg: oklch(0.24 0.03 175);
  --color-tgx15-card: #20302c;
  --color-tgx15-card: oklch(0.28 0.03 175);
  --color-tgx15-cardhot: #26403a;
  --color-tgx15-cardhot: oklch(0.33 0.05 170);
  --color-tgx15-edge: #395049;
  --color-tgx15-edge: oklch(0.4 0.04 175);
  --color-tgx15-mint: #8fe3c4;
  --color-tgx15-mint: oklch(0.86 0.12 165);
  --color-tgx15-minthover: #a9ecd4;
  --color-tgx15-minthover: oklch(0.9 0.1 165);
  --color-tgx15-ink: #12241f;
  --color-tgx15-ink: oklch(0.22 0.03 175);
  --color-tgx15-dim: #b5c9c2;
  --color-tgx15-dim: oklch(0.8 0.02 175);
  --font-tgx15-sans: 'Inter Tight', system-ui, sans-serif;
}

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

@supports not (grid-template-rows: subgrid) {
  .tgx-15 article {
    grid-template-rows: auto auto 1fr auto;
  }
}

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-tgx15-bg: #1a2724;
  --color-tgx15-bg: oklch(0.24 0.03 175);
  --color-tgx15-card: #20302c;
  --color-tgx15-card: oklch(0.28 0.03 175);
  --color-tgx15-cardhot: #26403a;
  --color-tgx15-cardhot: oklch(0.33 0.05 170);
  --color-tgx15-edge: #395049;
  --color-tgx15-edge: oklch(0.4 0.04 175);
  --color-tgx15-mint: #8fe3c4;
  --color-tgx15-mint: oklch(0.86 0.12 165);
  --color-tgx15-minthover: #a9ecd4;
  --color-tgx15-minthover: oklch(0.9 0.1 165);
  --color-tgx15-ink: #12241f;
  --color-tgx15-ink: oklch(0.22 0.03 175);
  --color-tgx15-dim: #b5c9c2;
  --color-tgx15-dim: oklch(0.8 0.02 175);
  --font-tgx15-sans: 'Inter Tight', system-ui, sans-serif;
}

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

@supports not (grid-template-rows: subgrid) {
  .tgx-15 article {
    grid-template-rows: auto auto 1fr auto;
  }
}
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;700&display=swap">

What changed in the port

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

  • The middle card's deliberately long title is the proof: it raises the shared track and all three buttons stay level, which is impossible to demonstrate with equal-length placeholder copy.
  • row-span-4 plus one arbitrary property is the shortest expression of subgrid in any syntax.
  • Product upgrade: generic Starter/Studio/Agency cards became a workflow template gallery with categories and a 'most used' card, so the alignment problem is the one a real gallery has.
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 Subgrid Cards with Perfectly Aligned Buttons
Source: https://codefronts.com/layouts/tailwind-css-grid-layouts/tailwind-subgrid-cards-aligned-buttons/

A template gallery where titles run to different lengths and descriptions to different depths — yet every badge, title, body and button sits on a shared line, because each card adopts the parent's row tracks. Flexbox's mt-auto workaround retires here.
## HTML
```html
<section class="tgx-15 w-full min-h-svh bg-tgx15-bg font-tgx15-sans p-6">
  <header class="flex items-end justify-between gap-4 flex-wrap mb-5">
    <div class="flex flex-col gap-1">
      <p class="text-[0.66rem] tracking-[0.18em] uppercase text-tgx15-mint">Relay · Templates</p>
      <h2 class="text-[1.35rem] font-semibold text-white tracking-[-0.01em]">Start from a workflow</h2>
    </div>
    <p class="text-[0.76rem] text-tgx15-dim">Every card spans the same four rows</p>
  </header>
  <div class="grid grid-cols-[repeat(auto-fit,minmax(min(210px,100%),1fr))] auto-rows-auto gap-4">
    <article class="row-span-4 [grid-template-rows:subgrid] grid gap-y-3 rounded-2xl border border-tgx15-edge bg-tgx15-card p-5">
      <p class="text-[0.64rem] tracking-[0.16em] uppercase text-tgx15-mint">Incident response</p>
      <h3 class="text-[1.05rem] leading-[1.3] font-semibold text-white text-balance">On-call triage</h3>
      <p class="text-[0.8rem] leading-[1.6] text-tgx15-dim">Route, acknowledge, escalate. Four steps, one channel.</p>
      <a href="#0" class="self-end justify-self-start inline-flex items-center min-h-11 px-4 rounded-full text-[0.82rem] font-semibold no-underline text-tgx15-ink bg-tgx15-mint transition-colors hover:bg-tgx15-minthover focus-visible:outline-2 focus-visible:outline-tgx15-mint focus-visible:outline-offset-[3px]">Use template</a>
    </article>
    <article class="row-span-4 [grid-template-rows:subgrid] grid gap-y-3 rounded-2xl border border-tgx15-mint bg-tgx15-cardhot p-5">
      <p class="text-[0.64rem] tracking-[0.16em] uppercase text-tgx15-mint">Release · most used</p>
      <h3 class="text-[1.05rem] leading-[1.3] font-semibold text-white text-balance">Progressive rollout with automatic rollback gates</h3>
      <p class="text-[0.8rem] leading-[1.6] text-tgx15-dim">Ship to 5%, watch error budget, promote or revert automatically. The long title above raises the title track for every sibling card — that is subgrid doing its job.</p>
      <a href="#0" class="self-end justify-self-start inline-flex items-center min-h-11 px-4 rounded-full text-[0.82rem] font-semibold no-underline text-tgx15-ink bg-tgx15-mint transition-colors hover:bg-tgx15-minthover focus-visible:outline-2 focus-visible:outline-tgx15-mint focus-visible:outline-offset-[3px]">Use template</a>
    </article>
    <article class="row-span-4 [grid-template-rows:subgrid] grid gap-y-3 rounded-2xl border border-tgx15-edge bg-tgx15-card p-5">
      <p class="text-[0.64rem] tracking-[0.16em] uppercase text-tgx15-mint">Reporting</p>
      <h3 class="text-[1.05rem] leading-[1.3] font-semibold text-white text-balance">Weekly digest</h3>
      <p class="text-[0.8rem] leading-[1.6] text-tgx15-dim">Short title, short copy — and the button still lands level with its neighbours, because the final track is shared rather than pushed down by content.</p>
      <a href="#0" class="self-end justify-self-start inline-flex items-center min-h-11 px-4 rounded-full text-[0.82rem] font-semibold no-underline text-tgx15-ink bg-tgx15-mint transition-colors hover:bg-tgx15-minthover focus-visible:outline-2 focus-visible:outline-tgx15-mint focus-visible:outline-offset-[3px]">Use template</a>
    </article>
  </div>
</section>
```
## CSS
```css
@import "tailwindcss";

@theme {
  --color-tgx15-bg: #1a2724;
  --color-tgx15-bg: oklch(0.24 0.03 175);
  --color-tgx15-card: #20302c;
  --color-tgx15-card: oklch(0.28 0.03 175);
  --color-tgx15-cardhot: #26403a;
  --color-tgx15-cardhot: oklch(0.33 0.05 170);
  --color-tgx15-edge: #395049;
  --color-tgx15-edge: oklch(0.4 0.04 175);
  --color-tgx15-mint: #8fe3c4;
  --color-tgx15-mint: oklch(0.86 0.12 165);
  --color-tgx15-minthover: #a9ecd4;
  --color-tgx15-minthover: oklch(0.9 0.1 165);
  --color-tgx15-ink: #12241f;
  --color-tgx15-ink: oklch(0.22 0.03 175);
  --color-tgx15-dim: #b5c9c2;
  --color-tgx15-dim: oklch(0.8 0.02 175);
  --font-tgx15-sans: 'Inter Tight', system-ui, sans-serif;
}

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

@supports not (grid-template-rows: subgrid) {
  .tgx-15 article {
    grid-template-rows: auto auto 1fr auto;
  }
}
```

How this works

Every card shares the parent's rows. A two-line title in one card raises the title track for all of them, and every button lands on the final track. Nested independent grids cannot do this; flexbox only pins the last element.

The span must match the child count. Four children, row-span-4. Add a fifth element to one card and that card's tracks step out of line with its siblings — the rigidity you accept in exchange for the alignment.

Make it yours

  • Add a thumbnail row by raising the span AND adding one element to every card.
  • Clamp rambling descriptions with line-clamp-3 so one card cannot stretch the shared track.
  • Columns can subgrid too: [grid-template-columns:subgrid] for icon + text alignment.

Gotchas — read before shipping

  • A forgotten element shifts every later track for that card only — the failure is per-card and easy to miss.
  • You cannot resize one card's title track locally; the tracks belong to the parent.
  • Test the @supports fallback — it is the only part you cannot see in a modern browser.

Browser support

ChromeSafariFirefoxEdge
117+16+128+117+

subgrid is Baseline 2023; the @supports block covers the stragglers.

Techniques used in this demo

Search CodeFronts

Loading…