30 Tailwind CSS Grid Layouts
19 / 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 Video Thumbnail Grid with Zero Layout Shift

A course catalogue: 16:9 thumbnails reserved before any pixel loads, duration badges, progress bars on started lessons, and instructor lines. Tailwind ships aspect-video, so the CLS fix is one word.

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-19 w-full min-h-svh bg-tgx19-bg font-tgx19-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-tgx19-dim">Layout School · Track 2</p>
      <h2 class="text-[1.35rem] font-semibold text-tgx19-ink tracking-[-0.01em]">CSS Grid, end to end</h2>
    </div>
    <p class="text-[0.76rem] text-tgx19-dim tabular-nums">4 of 18 lessons · 2h 12m left</p>
  </header>
  <div class="grid grid-cols-[repeat(auto-fit,minmax(min(220px,100%),1fr))] gap-5">
    <article class="group flex flex-col gap-2.5">
      <a href="#0" class="block no-underline rounded-xl focus-visible:outline-2 focus-visible:outline-tgx19-cyan focus-visible:outline-offset-2">
        <div class="grid w-full aspect-video rounded-xl overflow-hidden bg-tgx19-cell relative outline-offset-2 outline-tgx19-cyan group-hover:outline-2">
          <img src="https://images.unsplash.com/photo-1498050108023-c5249f4df085?w=640&h=360&q=80&auto=format&fit=crop" alt="Laptop screen showing code in a dim room" loading="lazy" class="absolute inset-0 w-full h-full object-cover">
          <span class="relative place-self-end m-2 text-[0.66rem] tabular-nums text-white bg-black/75 rounded px-1.5 py-0.5">12:04</span>
        </div>
      </a>
      <div class="flex flex-col gap-1.5">
        <h3 class="text-[0.9rem] leading-[1.35] font-medium text-tgx19-ink"><a href="#0" class="no-underline text-inherit hover:underline underline-offset-2 focus-visible:outline-2 focus-visible:outline-tgx19-cyan focus-visible:outline-offset-2 rounded">Tracks, lines and the implicit grid</a></h3>
        <p class="text-[0.74rem] text-tgx19-dim">Marit Solheim · Lesson 1</p>
        <div role="progressbar" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100" aria-label="Lesson 1 progress" class="h-1 rounded-full bg-tgx19-track overflow-hidden"><span class="block h-full w-full bg-tgx19-done"></span></div>
      </div>
    </article>
    <article class="group flex flex-col gap-2.5">
      <a href="#0" class="block no-underline rounded-xl focus-visible:outline-2 focus-visible:outline-tgx19-cyan focus-visible:outline-offset-2">
        <div class="grid w-full aspect-video rounded-xl overflow-hidden bg-tgx19-cell relative outline-offset-2 outline-tgx19-cyan group-hover:outline-2">
          <img src="https://images.unsplash.com/photo-1461749280684-dccba630e2f6?w=640&h=360&q=80&auto=format&fit=crop" alt="Close-up of code on a monitor with syntax colours" loading="lazy" class="absolute inset-0 w-full h-full object-cover">
          <span class="relative place-self-end m-2 text-[0.66rem] tabular-nums text-white bg-black/75 rounded px-1.5 py-0.5">8:47</span>
        </div>
      </a>
      <div class="flex flex-col gap-1.5">
        <h3 class="text-[0.9rem] leading-[1.35] font-medium text-tgx19-ink"><a href="#0" class="no-underline text-inherit hover:underline underline-offset-2 focus-visible:outline-2 focus-visible:outline-tgx19-cyan focus-visible:outline-offset-2 rounded">Subgrid in practice</a></h3>
        <p class="text-[0.74rem] text-tgx19-dim">Marit Solheim · Lesson 2</p>
        <div role="progressbar" aria-valuenow="62" aria-valuemin="0" aria-valuemax="100" aria-label="Lesson 2 progress" class="h-1 rounded-full bg-tgx19-track overflow-hidden"><span class="block h-full w-[62%] bg-tgx19-cyan"></span></div>
      </div>
    </article>
    <article class="group flex flex-col gap-2.5">
      <a href="#0" class="block no-underline rounded-xl focus-visible:outline-2 focus-visible:outline-tgx19-cyan focus-visible:outline-offset-2">
        <div class="grid w-full aspect-video rounded-xl overflow-hidden bg-tgx19-cell relative outline-offset-2 outline-tgx19-cyan group-hover:outline-2">
          <img src="https://images.unsplash.com/photo-1555066931-4365d14bab8c?w=640&h=360&q=80&auto=format&fit=crop" alt="Terminal window and editor split across a widescreen display" loading="lazy" class="absolute inset-0 w-full h-full object-cover">
          <span class="relative place-self-end m-2 text-[0.66rem] tabular-nums text-white bg-black/75 rounded px-1.5 py-0.5">21:33</span>
        </div>
      </a>
      <div class="flex flex-col gap-1.5">
        <h3 class="text-[0.9rem] leading-[1.35] font-medium text-tgx19-ink"><a href="#0" class="no-underline text-inherit hover:underline underline-offset-2 focus-visible:outline-2 focus-visible:outline-tgx19-cyan focus-visible:outline-offset-2 rounded">Container queries, deep dive</a></h3>
        <p class="text-[0.74rem] text-tgx19-dim">Tomás Rivas · Lesson 3</p>
        <div role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" aria-label="Lesson 3 progress" class="h-1 rounded-full bg-tgx19-track overflow-hidden"><span class="block h-full w-0 bg-tgx19-cyan"></span></div>
      </div>
    </article>
    <article class="group flex flex-col gap-2.5">
      <a href="#0" class="block no-underline rounded-xl focus-visible:outline-2 focus-visible:outline-tgx19-cyan focus-visible:outline-offset-2">
        <div class="grid w-full aspect-video rounded-xl overflow-hidden bg-tgx19-cell relative outline-offset-2 outline-tgx19-cyan group-hover:outline-2">
          <img src="https://images.unsplash.com/photo-1517336714731-489689fd1ca8?w=640&h=360&q=80&auto=format&fit=crop" alt="Laptop open on a desk beside a notebook and coffee" loading="lazy" class="absolute inset-0 w-full h-full object-cover">
          <span class="relative place-self-end m-2 text-[0.66rem] tabular-nums text-white bg-black/75 rounded px-1.5 py-0.5">6:15</span>
        </div>
      </a>
      <div class="flex flex-col gap-1.5">
        <h3 class="text-[0.9rem] leading-[1.35] font-medium text-tgx19-ink"><a href="#0" class="no-underline text-inherit hover:underline underline-offset-2 focus-visible:outline-2 focus-visible:outline-tgx19-cyan focus-visible:outline-offset-2 rounded">clip-path shapes without SVG</a></h3>
        <p class="text-[0.74rem] text-tgx19-dim">Tomás Rivas · Lesson 4</p>
        <div role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" aria-label="Lesson 4 progress" class="h-1 rounded-full bg-tgx19-track overflow-hidden"><span class="block h-full w-0 bg-tgx19-cyan"></span></div>
      </div>
    </article>
  </div>
</section>
@import "tailwindcss";

@theme {
  --color-tgx19-bg: #14181c;
  --color-tgx19-bg: oklch(0.18 0.01 220);
  --color-tgx19-cell: #202830;
  --color-tgx19-cell: oklch(0.25 0.015 220);
  --color-tgx19-track: #2c363e;
  --color-tgx19-track: oklch(0.3 0.015 220);
  --color-tgx19-ink: #eef2f4;
  --color-tgx19-ink: oklch(0.95 0.01 220);
  --color-tgx19-dim: #9fabb2;
  --color-tgx19-dim: oklch(0.74 0.015 220);
  --color-tgx19-cyan: #79d2e3;
  --color-tgx19-cyan: oklch(0.82 0.1 210);
  --color-tgx19-done: #8ce0ae;
  --color-tgx19-done: oklch(0.85 0.14 150);
  --font-tgx19-sans: 'Inter Tight', system-ui, sans-serif;
}

.tgx-19 {
  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-tgx19-bg: #14181c;
  --color-tgx19-bg: oklch(0.18 0.01 220);
  --color-tgx19-cell: #202830;
  --color-tgx19-cell: oklch(0.25 0.015 220);
  --color-tgx19-track: #2c363e;
  --color-tgx19-track: oklch(0.3 0.015 220);
  --color-tgx19-ink: #eef2f4;
  --color-tgx19-ink: oklch(0.95 0.01 220);
  --color-tgx19-dim: #9fabb2;
  --color-tgx19-dim: oklch(0.74 0.015 220);
  --color-tgx19-cyan: #79d2e3;
  --color-tgx19-cyan: oklch(0.82 0.1 210);
  --color-tgx19-done: #8ce0ae;
  --color-tgx19-done: oklch(0.85 0.14 150);
  --font-tgx19-sans: 'Inter Tight', system-ui, sans-serif;
}

.tgx-19 {
  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&display=swap">

What changed in the port

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

  • Progress bars are real role="progressbar" elements with values, so 'watched 62%' is available to a screen reader rather than implied by a coloured strip.
  • The duration badge sits in the grid as a flow item with a margin, which keeps it inside the reserved box even when the image fails to load.
  • Product upgrade: four abstract tiles became a course track with instructors, lesson numbers, per-lesson progress and a header showing remaining time — and real thumbnails make the CLS reservation visible.
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 Video Thumbnail Grid with Zero Layout Shift
Source: https://codefronts.com/layouts/tailwind-css-grid-layouts/tailwind-video-thumbnail-grid-zero-layout-shift/

A course catalogue: 16:9 thumbnails reserved before any pixel loads, duration badges, progress bars on started lessons, and instructor lines. Tailwind ships aspect-video, so the CLS fix is one word.
## HTML
```html
<section class="tgx-19 w-full min-h-svh bg-tgx19-bg font-tgx19-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-tgx19-dim">Layout School · Track 2</p>
      <h2 class="text-[1.35rem] font-semibold text-tgx19-ink tracking-[-0.01em]">CSS Grid, end to end</h2>
    </div>
    <p class="text-[0.76rem] text-tgx19-dim tabular-nums">4 of 18 lessons · 2h 12m left</p>
  </header>
  <div class="grid grid-cols-[repeat(auto-fit,minmax(min(220px,100%),1fr))] gap-5">
    <article class="group flex flex-col gap-2.5">
      <a href="#0" class="block no-underline rounded-xl focus-visible:outline-2 focus-visible:outline-tgx19-cyan focus-visible:outline-offset-2">
        <div class="grid w-full aspect-video rounded-xl overflow-hidden bg-tgx19-cell relative outline-offset-2 outline-tgx19-cyan group-hover:outline-2">
          <img src="https://images.unsplash.com/photo-1498050108023-c5249f4df085?w=640&h=360&q=80&auto=format&fit=crop" alt="Laptop screen showing code in a dim room" loading="lazy" class="absolute inset-0 w-full h-full object-cover">
          <span class="relative place-self-end m-2 text-[0.66rem] tabular-nums text-white bg-black/75 rounded px-1.5 py-0.5">12:04</span>
        </div>
      </a>
      <div class="flex flex-col gap-1.5">
        <h3 class="text-[0.9rem] leading-[1.35] font-medium text-tgx19-ink"><a href="#0" class="no-underline text-inherit hover:underline underline-offset-2 focus-visible:outline-2 focus-visible:outline-tgx19-cyan focus-visible:outline-offset-2 rounded">Tracks, lines and the implicit grid</a></h3>
        <p class="text-[0.74rem] text-tgx19-dim">Marit Solheim · Lesson 1</p>
        <div role="progressbar" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100" aria-label="Lesson 1 progress" class="h-1 rounded-full bg-tgx19-track overflow-hidden"><span class="block h-full w-full bg-tgx19-done"></span></div>
      </div>
    </article>
    <article class="group flex flex-col gap-2.5">
      <a href="#0" class="block no-underline rounded-xl focus-visible:outline-2 focus-visible:outline-tgx19-cyan focus-visible:outline-offset-2">
        <div class="grid w-full aspect-video rounded-xl overflow-hidden bg-tgx19-cell relative outline-offset-2 outline-tgx19-cyan group-hover:outline-2">
          <img src="https://images.unsplash.com/photo-1461749280684-dccba630e2f6?w=640&h=360&q=80&auto=format&fit=crop" alt="Close-up of code on a monitor with syntax colours" loading="lazy" class="absolute inset-0 w-full h-full object-cover">
          <span class="relative place-self-end m-2 text-[0.66rem] tabular-nums text-white bg-black/75 rounded px-1.5 py-0.5">8:47</span>
        </div>
      </a>
      <div class="flex flex-col gap-1.5">
        <h3 class="text-[0.9rem] leading-[1.35] font-medium text-tgx19-ink"><a href="#0" class="no-underline text-inherit hover:underline underline-offset-2 focus-visible:outline-2 focus-visible:outline-tgx19-cyan focus-visible:outline-offset-2 rounded">Subgrid in practice</a></h3>
        <p class="text-[0.74rem] text-tgx19-dim">Marit Solheim · Lesson 2</p>
        <div role="progressbar" aria-valuenow="62" aria-valuemin="0" aria-valuemax="100" aria-label="Lesson 2 progress" class="h-1 rounded-full bg-tgx19-track overflow-hidden"><span class="block h-full w-[62%] bg-tgx19-cyan"></span></div>
      </div>
    </article>
    <article class="group flex flex-col gap-2.5">
      <a href="#0" class="block no-underline rounded-xl focus-visible:outline-2 focus-visible:outline-tgx19-cyan focus-visible:outline-offset-2">
        <div class="grid w-full aspect-video rounded-xl overflow-hidden bg-tgx19-cell relative outline-offset-2 outline-tgx19-cyan group-hover:outline-2">
          <img src="https://images.unsplash.com/photo-1555066931-4365d14bab8c?w=640&h=360&q=80&auto=format&fit=crop" alt="Terminal window and editor split across a widescreen display" loading="lazy" class="absolute inset-0 w-full h-full object-cover">
          <span class="relative place-self-end m-2 text-[0.66rem] tabular-nums text-white bg-black/75 rounded px-1.5 py-0.5">21:33</span>
        </div>
      </a>
      <div class="flex flex-col gap-1.5">
        <h3 class="text-[0.9rem] leading-[1.35] font-medium text-tgx19-ink"><a href="#0" class="no-underline text-inherit hover:underline underline-offset-2 focus-visible:outline-2 focus-visible:outline-tgx19-cyan focus-visible:outline-offset-2 rounded">Container queries, deep dive</a></h3>
        <p class="text-[0.74rem] text-tgx19-dim">Tomás Rivas · Lesson 3</p>
        <div role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" aria-label="Lesson 3 progress" class="h-1 rounded-full bg-tgx19-track overflow-hidden"><span class="block h-full w-0 bg-tgx19-cyan"></span></div>
      </div>
    </article>
    <article class="group flex flex-col gap-2.5">
      <a href="#0" class="block no-underline rounded-xl focus-visible:outline-2 focus-visible:outline-tgx19-cyan focus-visible:outline-offset-2">
        <div class="grid w-full aspect-video rounded-xl overflow-hidden bg-tgx19-cell relative outline-offset-2 outline-tgx19-cyan group-hover:outline-2">
          <img src="https://images.unsplash.com/photo-1517336714731-489689fd1ca8?w=640&h=360&q=80&auto=format&fit=crop" alt="Laptop open on a desk beside a notebook and coffee" loading="lazy" class="absolute inset-0 w-full h-full object-cover">
          <span class="relative place-self-end m-2 text-[0.66rem] tabular-nums text-white bg-black/75 rounded px-1.5 py-0.5">6:15</span>
        </div>
      </a>
      <div class="flex flex-col gap-1.5">
        <h3 class="text-[0.9rem] leading-[1.35] font-medium text-tgx19-ink"><a href="#0" class="no-underline text-inherit hover:underline underline-offset-2 focus-visible:outline-2 focus-visible:outline-tgx19-cyan focus-visible:outline-offset-2 rounded">clip-path shapes without SVG</a></h3>
        <p class="text-[0.74rem] text-tgx19-dim">Tomás Rivas · Lesson 4</p>
        <div role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" aria-label="Lesson 4 progress" class="h-1 rounded-full bg-tgx19-track overflow-hidden"><span class="block h-full w-0 bg-tgx19-cyan"></span></div>
      </div>
    </article>
  </div>
</section>
```
## CSS
```css
@import "tailwindcss";

@theme {
  --color-tgx19-bg: #14181c;
  --color-tgx19-bg: oklch(0.18 0.01 220);
  --color-tgx19-cell: #202830;
  --color-tgx19-cell: oklch(0.25 0.015 220);
  --color-tgx19-track: #2c363e;
  --color-tgx19-track: oklch(0.3 0.015 220);
  --color-tgx19-ink: #eef2f4;
  --color-tgx19-ink: oklch(0.95 0.01 220);
  --color-tgx19-dim: #9fabb2;
  --color-tgx19-dim: oklch(0.74 0.015 220);
  --color-tgx19-cyan: #79d2e3;
  --color-tgx19-cyan: oklch(0.82 0.1 210);
  --color-tgx19-done: #8ce0ae;
  --color-tgx19-done: oklch(0.85 0.14 150);
  --font-tgx19-sans: 'Inter Tight', system-ui, sans-serif;
}

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

How this works

The box exists before the pixels. A slot with aspect-video and w-full occupies full size whether the image loaded, failed, or never arrives — Google's recommended CLS fix, one utility long.

The overlay is a grid cell. The slot is itself a grid; place-self-end parks the badge bottom-right using the slot's padding as the inset, and the badge can never escape the reserved box.

Make it yours

  • Tokenise ratios in @theme (--aspect-poster: 4/5) and use aspect-poster.
  • Badge corner is one utility: place-self-start for 'New', place-self-end for duration.
  • Hover play state: group-hover:scale-105 on the image, clipped by overflow-hidden.

Gotchas — read before shipping

  • aspect-ratio yields to an explicit height — one stray h-* and the reservation silently stops.
  • Put the ratio on the WRAPPER, not the <img>: broken-image rendering collapses the box in some engines.
  • A progress bar needs a real role="progressbar" with values, not just a coloured div.

Browser support

ChromeSafariFirefoxEdge
111+16.4+128+111+

aspect-ratio hit all engines in 2021 and is the entire trick.

Techniques used in this demo

Utilitiesfirst-class utility or variant

Search CodeFronts

Loading…