15 / 30
All 30 in 30 Tailwind CSS Grid Layouts
- 01Tailwind Full-Bleed Article Layout for Long-Form Editorial
- 02Tailwind Docs Layout with Sticky Table of Contents
- 03Tailwind Photo Gallery Grid with auto-fill and Real Images
- 04Tailwind Holy Grail Page Layout for a News Site
- 05Tailwind Data Table with Subgrid Rows and Status Pills
- 06Tailwind Overlapping Card Hero for a Case Study
- 07Tailwind Help Center Layout with Fixed Sidebars
- 08Tailwind 12 Column Grid System for Marketing Pages
- 09Tailwind Bento Grid for a Product Feature Section
- 10Tailwind Magazine Spread Layout with Overlapping Headline
- 11Tailwind Responsive Card Grid for an Integrations Directory
- 12Tailwind CMS Category Grid that Compacts Itself with has()
- 13Tailwind Masonry Layout for a Saved Ideas Board
- 14Tailwind Hexagon Team Grid with clip-path Avatars
- 15Tailwind Subgrid Cards with Perfectly Aligned Buttons
- 16Tailwind Analytics Dashboard Layout with Grid App Shell
- 17Tailwind Pricing Table with Subgrid and a Featured Plan
- 18Tailwind Kanban Board with Scroll Snap Columns
- 19Tailwind Video Thumbnail Grid with Zero Layout Shift
- 20Tailwind Container Query Card for Reusable Article Teasers
- 21Tailwind Diagonal Section Band with skewY Counter-Skew
- 22Tailwind Asymmetric Poster Hero with Layered Grid Regions
- 23Tailwind Mosaic Photo Wall with a Designed Span Sequence
- 24Tailwind Dense Grid Packing for a Mixed-Size Asset Library
- 25Tailwind Onboarding Stepper with CSS Counters
- 26Tailwind macOS Window Layout with Vibrancy Sidebar
- 27Tailwind Scroll Snap Carousel with Peeking Slides
- 28Tailwind Status Map UI with Grid Coordinate Pins
- 29Tailwind Logo Wall with 1px Gap Hairline Dividers
- 30Tailwind Periodic Table Layout with Grid Coordinates
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.
Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time
Untitled UI React · Affiliate link
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><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;
}
}@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.
<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-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;
}
}@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;
}
}<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">
<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-4plus 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.
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;
}
}
```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-3so 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
@supportsfallback — it is the only part you cannot see in a modern browser.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 117+ | 16+ | 128+ | 117+ |
subgrid is Baseline 2023; the @supports block covers the stragglers.