24 / 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 Dense Grid Packing for a Mixed-Size Asset Library
A brand-asset library where tiles come in three footprints and the grid refuses to leave holes. The numbers are upload order, so you can watch the algorithm pull later assets backwards — and see exactly when that trade is acceptable.
Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time
Untitled UI React · Affiliate link
The code
<section class="tgx-24 w-full min-h-svh bg-tgx24-bg font-tgx24-sans p-6">
<header class="flex items-start justify-between gap-4 flex-wrap mb-4">
<div class="flex flex-col gap-1">
<p class="font-tgx24-mono text-[0.66rem] tracking-[0.16em] uppercase text-tgx24-note">Brandkit · Asset library</p>
<h2 class="text-[1.25rem] font-semibold text-white tracking-[-0.01em]">Autumn campaign · 15 assets</h2>
</div>
<p class="text-[0.72rem] leading-[1.5] text-tgx24-note max-w-[38ch]">Numbers are upload order. Tab order follows them too — which is why dense packing belongs on a browsing surface, not a ranked list.</p>
</header>
<div class="grid grid-cols-[repeat(auto-fit,minmax(min(84px,100%),1fr))] auto-rows-[72px] grid-flow-dense gap-2">
<div class="col-span-2 grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellA p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">01 · banner</span><strong class="text-[0.78rem] font-medium text-white">Hero 3200×800</strong></div>
<div class="grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellB p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">02</span><strong class="text-[0.72rem] font-medium text-white">Icon</strong></div>
<div class="col-span-2 row-span-2 grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellA p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">03 · key art</span><strong class="text-[0.78rem] font-medium text-white">Poster 2000×2500</strong></div>
<div class="grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellB p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">04</span><strong class="text-[0.72rem] font-medium text-white">Swatch</strong></div>
<div class="col-span-2 grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellA p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">05 · social</span><strong class="text-[0.78rem] font-medium text-white">OG 1200×630</strong></div>
<div class="grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellB p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">06</span><strong class="text-[0.72rem] font-medium text-white">Mark</strong></div>
<div class="grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellA p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">07</span><strong class="text-[0.72rem] font-medium text-white">Favicon</strong></div>
<div class="col-span-2 grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellB p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">08 · email</span><strong class="text-[0.78rem] font-medium text-white">Header 600×200</strong></div>
<div class="grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellA p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">09</span><strong class="text-[0.72rem] font-medium text-white">Badge</strong></div>
<div class="grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellB p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">10</span><strong class="text-[0.72rem] font-medium text-white">Sticker</strong></div>
<div class="row-span-2 grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellA p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">11 · story</span><strong class="text-[0.78rem] font-medium text-white">1080×1920</strong></div>
<div class="grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellB p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">12</span><strong class="text-[0.72rem] font-medium text-white">Avatar</strong></div>
<div class="grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellA p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">13</span><strong class="text-[0.72rem] font-medium text-white">Glyph</strong></div>
<div class="col-span-2 grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellB p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">14 · print</span><strong class="text-[0.78rem] font-medium text-white">A4 flyer</strong></div>
<div class="grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellA p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">15</span><strong class="text-[0.72rem] font-medium text-white">Tile</strong></div>
</div>
</section><section class="tgx-24 w-full min-h-svh bg-tgx24-bg font-tgx24-sans p-6">
<header class="flex items-start justify-between gap-4 flex-wrap mb-4">
<div class="flex flex-col gap-1">
<p class="font-tgx24-mono text-[0.66rem] tracking-[0.16em] uppercase text-tgx24-note">Brandkit · Asset library</p>
<h2 class="text-[1.25rem] font-semibold text-white tracking-[-0.01em]">Autumn campaign · 15 assets</h2>
</div>
<p class="text-[0.72rem] leading-[1.5] text-tgx24-note max-w-[38ch]">Numbers are upload order. Tab order follows them too — which is why dense packing belongs on a browsing surface, not a ranked list.</p>
</header>
<div class="grid grid-cols-[repeat(auto-fit,minmax(min(84px,100%),1fr))] auto-rows-[72px] grid-flow-dense gap-2">
<div class="col-span-2 grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellA p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">01 · banner</span><strong class="text-[0.78rem] font-medium text-white">Hero 3200×800</strong></div>
<div class="grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellB p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">02</span><strong class="text-[0.72rem] font-medium text-white">Icon</strong></div>
<div class="col-span-2 row-span-2 grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellA p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">03 · key art</span><strong class="text-[0.78rem] font-medium text-white">Poster 2000×2500</strong></div>
<div class="grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellB p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">04</span><strong class="text-[0.72rem] font-medium text-white">Swatch</strong></div>
<div class="col-span-2 grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellA p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">05 · social</span><strong class="text-[0.78rem] font-medium text-white">OG 1200×630</strong></div>
<div class="grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellB p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">06</span><strong class="text-[0.72rem] font-medium text-white">Mark</strong></div>
<div class="grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellA p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">07</span><strong class="text-[0.72rem] font-medium text-white">Favicon</strong></div>
<div class="col-span-2 grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellB p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">08 · email</span><strong class="text-[0.78rem] font-medium text-white">Header 600×200</strong></div>
<div class="grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellA p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">09</span><strong class="text-[0.72rem] font-medium text-white">Badge</strong></div>
<div class="grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellB p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">10</span><strong class="text-[0.72rem] font-medium text-white">Sticker</strong></div>
<div class="row-span-2 grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellA p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">11 · story</span><strong class="text-[0.78rem] font-medium text-white">1080×1920</strong></div>
<div class="grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellB p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">12</span><strong class="text-[0.72rem] font-medium text-white">Avatar</strong></div>
<div class="grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellA p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">13</span><strong class="text-[0.72rem] font-medium text-white">Glyph</strong></div>
<div class="col-span-2 grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellB p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">14 · print</span><strong class="text-[0.78rem] font-medium text-white">A4 flyer</strong></div>
<div class="grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellA p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">15</span><strong class="text-[0.72rem] font-medium text-white">Tile</strong></div>
</div>
</section>@import "tailwindcss";
@theme {
--color-tgx24-bg: #1e1426;
--color-tgx24-bg: oklch(0.2 0.03 310);
--color-tgx24-cellA: #47286a;
--color-tgx24-cellA: oklch(0.36 0.11 310);
--color-tgx24-cellB: #3a2157;
--color-tgx24-cellB: oklch(0.31 0.09 310);
--color-tgx24-edge: #6b46a0;
--color-tgx24-edge: oklch(0.48 0.14 310);
--color-tgx24-note: #c6b0dd;
--color-tgx24-note: oklch(0.82 0.05 310);
--font-tgx24-sans: 'Inter Tight', system-ui, sans-serif;
--font-tgx24-mono: 'JetBrains Mono', ui-monospace, monospace;
}
.tgx-24 {
width: 100%;
min-height: 100svh;
}@import "tailwindcss";
@theme {
--color-tgx24-bg: #1e1426;
--color-tgx24-bg: oklch(0.2 0.03 310);
--color-tgx24-cellA: #47286a;
--color-tgx24-cellA: oklch(0.36 0.11 310);
--color-tgx24-cellB: #3a2157;
--color-tgx24-cellB: oklch(0.31 0.09 310);
--color-tgx24-edge: #6b46a0;
--color-tgx24-edge: oklch(0.48 0.14 310);
--color-tgx24-note: #c6b0dd;
--color-tgx24-note: oklch(0.82 0.05 310);
--font-tgx24-sans: 'Inter Tight', system-ui, sans-serif;
--font-tgx24-mono: 'JetBrains Mono', ui-monospace, monospace;
}
.tgx-24 {
width: 100%;
min-height: 100svh;
}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-tgx24-bg: #1e1426;
--color-tgx24-bg: oklch(0.2 0.03 310);
--color-tgx24-cellA: #47286a;
--color-tgx24-cellA: oklch(0.36 0.11 310);
--color-tgx24-cellB: #3a2157;
--color-tgx24-cellB: oklch(0.31 0.09 310);
--color-tgx24-edge: #6b46a0;
--color-tgx24-edge: oklch(0.48 0.14 310);
--color-tgx24-note: #c6b0dd;
--color-tgx24-note: oklch(0.82 0.05 310);
--font-tgx24-sans: 'Inter Tight', system-ui, sans-serif;
--font-tgx24-mono: 'JetBrains Mono', ui-monospace, monospace;
}
.tgx-24 {
width: 100%;
min-height: 100svh;
}@import "tailwindcss";
@theme {
--color-tgx24-bg: #1e1426;
--color-tgx24-bg: oklch(0.2 0.03 310);
--color-tgx24-cellA: #47286a;
--color-tgx24-cellA: oklch(0.36 0.11 310);
--color-tgx24-cellB: #3a2157;
--color-tgx24-cellB: oklch(0.31 0.09 310);
--color-tgx24-edge: #6b46a0;
--color-tgx24-edge: oklch(0.48 0.14 310);
--color-tgx24-note: #c6b0dd;
--color-tgx24-note: oklch(0.82 0.05 310);
--font-tgx24-sans: 'Inter Tight', system-ui, sans-serif;
--font-tgx24-mono: 'JetBrains Mono', ui-monospace, monospace;
}
.tgx-24 {
width: 100%;
min-height: 100svh;
}<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;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&family=JetBrains+Mono:wght@400;500;700&display=swap">What changed in the port
Which parts became utilities, which stayed CSS, and why.
- Giving each numbered tile an asset name and a size makes the reordering legible as a real consequence: asset 07 sits before 05, and you can decide whether that matters for a library (it does not) or a feed (it does).
- Tiles use
content-betweenso the upload number sits at the top and the name at the bottom, which keeps the DOM order scannable even after the algorithm moves things. - Product upgrade: bare digits became a brand-asset library, and the WCAG focus-order caveat moved from a stylesheet comment into the page header where a reader will actually see it.
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 Dense Grid Packing for a Mixed-Size Asset Library
Source: https://codefronts.com/layouts/tailwind-css-grid-layouts/tailwind-dense-grid-packing-asset-library/
A brand-asset library where tiles come in three footprints and the grid refuses to leave holes. The numbers are upload order, so you can watch the algorithm pull later assets backwards — and see exactly when that trade is acceptable.
## HTML
```html
<section class="tgx-24 w-full min-h-svh bg-tgx24-bg font-tgx24-sans p-6">
<header class="flex items-start justify-between gap-4 flex-wrap mb-4">
<div class="flex flex-col gap-1">
<p class="font-tgx24-mono text-[0.66rem] tracking-[0.16em] uppercase text-tgx24-note">Brandkit · Asset library</p>
<h2 class="text-[1.25rem] font-semibold text-white tracking-[-0.01em]">Autumn campaign · 15 assets</h2>
</div>
<p class="text-[0.72rem] leading-[1.5] text-tgx24-note max-w-[38ch]">Numbers are upload order. Tab order follows them too — which is why dense packing belongs on a browsing surface, not a ranked list.</p>
</header>
<div class="grid grid-cols-[repeat(auto-fit,minmax(min(84px,100%),1fr))] auto-rows-[72px] grid-flow-dense gap-2">
<div class="col-span-2 grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellA p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">01 · banner</span><strong class="text-[0.78rem] font-medium text-white">Hero 3200×800</strong></div>
<div class="grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellB p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">02</span><strong class="text-[0.72rem] font-medium text-white">Icon</strong></div>
<div class="col-span-2 row-span-2 grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellA p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">03 · key art</span><strong class="text-[0.78rem] font-medium text-white">Poster 2000×2500</strong></div>
<div class="grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellB p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">04</span><strong class="text-[0.72rem] font-medium text-white">Swatch</strong></div>
<div class="col-span-2 grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellA p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">05 · social</span><strong class="text-[0.78rem] font-medium text-white">OG 1200×630</strong></div>
<div class="grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellB p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">06</span><strong class="text-[0.72rem] font-medium text-white">Mark</strong></div>
<div class="grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellA p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">07</span><strong class="text-[0.72rem] font-medium text-white">Favicon</strong></div>
<div class="col-span-2 grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellB p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">08 · email</span><strong class="text-[0.78rem] font-medium text-white">Header 600×200</strong></div>
<div class="grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellA p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">09</span><strong class="text-[0.72rem] font-medium text-white">Badge</strong></div>
<div class="grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellB p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">10</span><strong class="text-[0.72rem] font-medium text-white">Sticker</strong></div>
<div class="row-span-2 grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellA p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">11 · story</span><strong class="text-[0.78rem] font-medium text-white">1080×1920</strong></div>
<div class="grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellB p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">12</span><strong class="text-[0.72rem] font-medium text-white">Avatar</strong></div>
<div class="grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellA p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">13</span><strong class="text-[0.72rem] font-medium text-white">Glyph</strong></div>
<div class="col-span-2 grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellB p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">14 · print</span><strong class="text-[0.78rem] font-medium text-white">A4 flyer</strong></div>
<div class="grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellA p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">15</span><strong class="text-[0.72rem] font-medium text-white">Tile</strong></div>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tgx24-bg: #1e1426;
--color-tgx24-bg: oklch(0.2 0.03 310);
--color-tgx24-cellA: #47286a;
--color-tgx24-cellA: oklch(0.36 0.11 310);
--color-tgx24-cellB: #3a2157;
--color-tgx24-cellB: oklch(0.31 0.09 310);
--color-tgx24-edge: #6b46a0;
--color-tgx24-edge: oklch(0.48 0.14 310);
--color-tgx24-note: #c6b0dd;
--color-tgx24-note: oklch(0.82 0.05 310);
--font-tgx24-sans: 'Inter Tight', system-ui, sans-serif;
--font-tgx24-mono: 'JetBrains Mono', ui-monospace, monospace;
}
.tgx-24 {
width: 100%;
min-height: 100svh;
}
```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 Dense Grid Packing for a Mixed-Size Asset Library
Source: https://codefronts.com/layouts/tailwind-css-grid-layouts/tailwind-dense-grid-packing-asset-library/
A brand-asset library where tiles come in three footprints and the grid refuses to leave holes. The numbers are upload order, so you can watch the algorithm pull later assets backwards — and see exactly when that trade is acceptable.
## HTML
```html
<section class="tgx-24 w-full min-h-svh bg-tgx24-bg font-tgx24-sans p-6">
<header class="flex items-start justify-between gap-4 flex-wrap mb-4">
<div class="flex flex-col gap-1">
<p class="font-tgx24-mono text-[0.66rem] tracking-[0.16em] uppercase text-tgx24-note">Brandkit · Asset library</p>
<h2 class="text-[1.25rem] font-semibold text-white tracking-[-0.01em]">Autumn campaign · 15 assets</h2>
</div>
<p class="text-[0.72rem] leading-[1.5] text-tgx24-note max-w-[38ch]">Numbers are upload order. Tab order follows them too — which is why dense packing belongs on a browsing surface, not a ranked list.</p>
</header>
<div class="grid grid-cols-[repeat(auto-fit,minmax(min(84px,100%),1fr))] auto-rows-[72px] grid-flow-dense gap-2">
<div class="col-span-2 grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellA p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">01 · banner</span><strong class="text-[0.78rem] font-medium text-white">Hero 3200×800</strong></div>
<div class="grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellB p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">02</span><strong class="text-[0.72rem] font-medium text-white">Icon</strong></div>
<div class="col-span-2 row-span-2 grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellA p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">03 · key art</span><strong class="text-[0.78rem] font-medium text-white">Poster 2000×2500</strong></div>
<div class="grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellB p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">04</span><strong class="text-[0.72rem] font-medium text-white">Swatch</strong></div>
<div class="col-span-2 grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellA p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">05 · social</span><strong class="text-[0.78rem] font-medium text-white">OG 1200×630</strong></div>
<div class="grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellB p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">06</span><strong class="text-[0.72rem] font-medium text-white">Mark</strong></div>
<div class="grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellA p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">07</span><strong class="text-[0.72rem] font-medium text-white">Favicon</strong></div>
<div class="col-span-2 grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellB p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">08 · email</span><strong class="text-[0.78rem] font-medium text-white">Header 600×200</strong></div>
<div class="grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellA p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">09</span><strong class="text-[0.72rem] font-medium text-white">Badge</strong></div>
<div class="grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellB p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">10</span><strong class="text-[0.72rem] font-medium text-white">Sticker</strong></div>
<div class="row-span-2 grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellA p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">11 · story</span><strong class="text-[0.78rem] font-medium text-white">1080×1920</strong></div>
<div class="grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellB p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">12</span><strong class="text-[0.72rem] font-medium text-white">Avatar</strong></div>
<div class="grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellA p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">13</span><strong class="text-[0.72rem] font-medium text-white">Glyph</strong></div>
<div class="col-span-2 grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellB p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">14 · print</span><strong class="text-[0.78rem] font-medium text-white">A4 flyer</strong></div>
<div class="grid content-between rounded-xl border border-tgx24-edge bg-tgx24-cellA p-2.5"><span class="font-tgx24-mono text-[0.62rem] text-tgx24-note">15</span><strong class="text-[0.72rem] font-medium text-white">Tile</strong></div>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tgx24-bg: #1e1426;
--color-tgx24-bg: oklch(0.2 0.03 310);
--color-tgx24-cellA: #47286a;
--color-tgx24-cellA: oklch(0.36 0.11 310);
--color-tgx24-cellB: #3a2157;
--color-tgx24-cellB: oklch(0.31 0.09 310);
--color-tgx24-edge: #6b46a0;
--color-tgx24-edge: oklch(0.48 0.14 310);
--color-tgx24-note: #c6b0dd;
--color-tgx24-note: oklch(0.82 0.05 310);
--font-tgx24-sans: 'Inter Tight', system-ui, sans-serif;
--font-tgx24-mono: 'JetBrains Mono', ui-monospace, monospace;
}
.tgx-24 {
width: 100%;
min-height: 100svh;
}
```How this works
Default flow leaves holes. A wide tile that does not fit the remaining tracks wraps; dense lets later small tiles jump backward into the gap.
Dense is for browsing surfaces. Asset libraries, moodboards, tag clouds — places where visual completeness beats sequence. It is wrong for ranked or chronological content, and keyboard focus still follows the DOM.
Make it yours
- Remove
grid-flow-denseto compare; the holes reappear instantly. - Constrain the chaos by keeping every span ≤ 2.
- For ranked content that must look gap-free, design the spans instead (demo 23).
Gotchas — read before shipping
- Never use dense where reading order carries meaning.
- Avoid it for grids of links unless order genuinely does not matter — WCAG 2.4.3.
- Dense cannot fix holes caused by spans wider than the remaining tracks at the grid's end.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
dense shipped with original grid; the lesson, not the support, is the constraint.