30 Tailwind CSS Grid Layouts
25 / 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 Onboarding Stepper with CSS Counters

A deploy-platform setup checklist: self-numbering circles from CSS counters, a connector drawn per step so it stops cleanly at the last one, completed steps marked by a data attribute and the current step announced with aria-current.

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-25 w-full min-h-svh bg-tgx25-bg font-tgx25-sans px-6 py-10">
  <div class="w-[min(560px,100%)] mx-auto flex flex-col gap-6">
    <header class="flex flex-col gap-2">
      <p class="text-[0.66rem] tracking-[0.18em] uppercase text-tgx25-gold">Relay · Setup</p>
      <h2 class="text-[1.4rem] font-semibold text-white tracking-[-0.01em]">Two steps left before your first deploy</h2>
      <div class="flex items-center gap-3">
        <div role="progressbar" aria-valuenow="50" aria-valuemin="0" aria-valuemax="100" aria-label="Setup progress" class="h-1.5 flex-1 rounded-full bg-tgx25-line overflow-hidden"><span class="block h-full w-1/2 bg-tgx25-gold"></span></div>
        <span class="text-[0.74rem] tabular-nums text-tgx25-dim">2 / 4</span>
      </div>
    </header>
    <ol class="list-none [counter-reset:tgx25] flex flex-col gap-7 m-0 p-0">
      <li data-done class="[counter-increment:tgx25] relative grid grid-cols-[44px_minmax(0,1fr)] gap-x-3.5 *:col-start-2 before:col-start-1 before:row-start-1 before:content-[counter(tgx25)] before:w-9 before:aspect-square before:rounded-full before:grid before:place-items-center before:font-bold before:text-[0.9rem] before:text-tgx25-dim before:bg-tgx25-bg before:border-2 before:border-tgx25-line before:z-10 after:content-[''] after:absolute after:left-[17px] after:top-10 after:w-0.5 after:h-[calc(100%-36px+1.75rem)] after:bg-tgx25-line last:after:content-none data-done:before:content-['✓'] data-done:before:text-tgx25-bg data-done:before:bg-tgx25-gold data-done:before:border-tgx25-gold data-done:after:bg-tgx25-gold">
        <h3 class="text-[0.95rem] font-semibold text-tgx25-ink pt-1.5">Create your workspace</h3>
        <p class="text-[0.82rem] leading-[1.6] text-tgx25-dim mt-1">northwind-freight · 6 members invited</p>
      </li>
      <li data-done class="[counter-increment:tgx25] relative grid grid-cols-[44px_minmax(0,1fr)] gap-x-3.5 *:col-start-2 before:col-start-1 before:row-start-1 before:content-[counter(tgx25)] before:w-9 before:aspect-square before:rounded-full before:grid before:place-items-center before:font-bold before:text-[0.9rem] before:text-tgx25-dim before:bg-tgx25-bg before:border-2 before:border-tgx25-line before:z-10 after:content-[''] after:absolute after:left-[17px] after:top-10 after:w-0.5 after:h-[calc(100%-36px+1.75rem)] after:bg-tgx25-line last:after:content-none data-done:before:content-['✓'] data-done:before:text-tgx25-bg data-done:before:bg-tgx25-gold data-done:before:border-tgx25-gold data-done:after:bg-tgx25-gold">
        <h3 class="text-[0.95rem] font-semibold text-tgx25-ink pt-1.5">Connect a repository</h3>
        <p class="text-[0.82rem] leading-[1.6] text-tgx25-dim mt-1">GitHub · northwind/freight-api on <code class="font-tgx25-mono text-tgx25-ink">main</code></p>
      </li>
      <li aria-current="step" class="[counter-increment:tgx25] relative grid grid-cols-[44px_minmax(0,1fr)] gap-x-3.5 *:col-start-2 before:col-start-1 before:row-start-1 before:content-[counter(tgx25)] before:w-9 before:aspect-square before:rounded-full before:grid before:place-items-center before:font-bold before:text-[0.9rem] before:text-tgx25-dim before:bg-tgx25-bg before:border-2 before:border-tgx25-line before:z-10 after:content-[''] after:absolute after:left-[17px] after:top-10 after:w-0.5 after:h-[calc(100%-36px+1.75rem)] after:bg-tgx25-line last:after:content-none aria-[current=step]:before:text-tgx25-gold aria-[current=step]:before:border-tgx25-gold aria-[current=step]:before:animate-tgx25-pulse motion-reduce:aria-[current=step]:before:animate-none">
        <h3 class="text-[0.95rem] font-semibold text-tgx25-ink pt-1.5">Configure the build</h3>
        <p class="text-[0.82rem] leading-[1.6] text-tgx25-dim mt-1">Set the build command and the output directory. We detected a Vite project.</p>
        <div class="flex gap-2 mt-3 flex-wrap">
          <button type="button" class="inline-flex items-center min-h-11 px-4 rounded-full bg-tgx25-gold text-tgx25-bg text-[0.82rem] font-semibold cursor-pointer transition-colors hover:bg-tgx25-goldhover focus-visible:outline-2 focus-visible:outline-tgx25-gold focus-visible:outline-offset-2">Use detected settings</button>
          <button type="button" class="inline-flex items-center min-h-11 px-4 rounded-full border border-tgx25-line text-tgx25-ink text-[0.82rem] font-medium cursor-pointer transition-colors hover:bg-tgx25-hover focus-visible:outline-2 focus-visible:outline-tgx25-gold focus-visible:outline-offset-2">Edit manually</button>
        </div>
      </li>
      <li class="[counter-increment:tgx25] relative grid grid-cols-[44px_minmax(0,1fr)] gap-x-3.5 *:col-start-2 before:col-start-1 before:row-start-1 before:content-[counter(tgx25)] before:w-9 before:aspect-square before:rounded-full before:grid before:place-items-center before:font-bold before:text-[0.9rem] before:text-tgx25-dim before:bg-tgx25-bg before:border-2 before:border-tgx25-line before:z-10 after:content-[''] after:absolute after:left-[17px] after:top-10 after:w-0.5 after:h-[calc(100%-36px+1.75rem)] after:bg-tgx25-line last:after:content-none">
        <h3 class="text-[0.95rem] font-semibold text-tgx25-ink pt-1.5">Ship to production</h3>
        <p class="text-[0.82rem] leading-[1.6] text-tgx25-dim mt-1">No line below this step — the <code class="font-tgx25-mono text-tgx25-ink">last:</code> variant suppresses the connector.</p>
      </li>
    </ol>
  </div>
</section>
@import "tailwindcss";

@theme {
  --color-tgx25-bg: #1d1a14;
  --color-tgx25-bg: oklch(0.2 0.015 85);
  --color-tgx25-line: #4a4234;
  --color-tgx25-line: oklch(0.38 0.03 85);
  --color-tgx25-hover: #2a251c;
  --color-tgx25-hover: oklch(0.26 0.02 85);
  --color-tgx25-gold: #edc167;
  --color-tgx25-gold: oklch(0.83 0.13 85);
  --color-tgx25-goldhover: #f3d089;
  --color-tgx25-goldhover: oklch(0.87 0.11 85);
  --color-tgx25-ink: #f0ebe1;
  --color-tgx25-ink: oklch(0.94 0.01 85);
  --color-tgx25-dim: #bab1a0;
  --color-tgx25-dim: oklch(0.78 0.02 85);
  --font-tgx25-sans: 'Inter Tight', system-ui, sans-serif;
  --font-tgx25-mono: 'JetBrains Mono', ui-monospace, monospace;
  --animate-tgx25-pulse: tgx25-pulse 2s ease-in-out infinite;
}

@keyframes tgx25-pulse {
  50% {
    box-shadow: 0 0 0 6px color-mix(in oklab, var(--color-tgx25-gold) 25%, transparent);
  }
}

.tgx-25 {
  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-tgx25-bg: #1d1a14;
  --color-tgx25-bg: oklch(0.2 0.015 85);
  --color-tgx25-line: #4a4234;
  --color-tgx25-line: oklch(0.38 0.03 85);
  --color-tgx25-hover: #2a251c;
  --color-tgx25-hover: oklch(0.26 0.02 85);
  --color-tgx25-gold: #edc167;
  --color-tgx25-gold: oklch(0.83 0.13 85);
  --color-tgx25-goldhover: #f3d089;
  --color-tgx25-goldhover: oklch(0.87 0.11 85);
  --color-tgx25-ink: #f0ebe1;
  --color-tgx25-ink: oklch(0.94 0.01 85);
  --color-tgx25-dim: #bab1a0;
  --color-tgx25-dim: oklch(0.78 0.02 85);
  --font-tgx25-sans: 'Inter Tight', system-ui, sans-serif;
  --font-tgx25-mono: 'JetBrains Mono', ui-monospace, monospace;
  --animate-tgx25-pulse: tgx25-pulse 2s ease-in-out infinite;
}

@keyframes tgx25-pulse {
  50% {
    box-shadow: 0 0 0 6px color-mix(in oklab, var(--color-tgx25-gold) 25%, transparent);
  }
}

.tgx-25 {
  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="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.

  • The current step carries real actions, which is the point a stepper demo usually skips: the connector must clear a taller step body, and the per-item ::after handles that automatically because its height is relative.
  • A --animate-* entry in @theme mints animate-tgx25-pulse while the keyframes stay CSS — the standard v4 division.
  • Product upgrade: generic onboarding copy became a deploy setup with a progress bar, detected-settings buttons and real repo details; state moved to data-done + aria-current, so the current step is announced rather than just coloured.
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 Onboarding Stepper with CSS Counters
Source: https://codefronts.com/layouts/tailwind-css-grid-layouts/tailwind-onboarding-stepper-css-counters/

A deploy-platform setup checklist: self-numbering circles from CSS counters, a connector drawn per step so it stops cleanly at the last one, completed steps marked by a data attribute and the current step announced with aria-current.
## HTML
```html
<section class="tgx-25 w-full min-h-svh bg-tgx25-bg font-tgx25-sans px-6 py-10">
  <div class="w-[min(560px,100%)] mx-auto flex flex-col gap-6">
    <header class="flex flex-col gap-2">
      <p class="text-[0.66rem] tracking-[0.18em] uppercase text-tgx25-gold">Relay · Setup</p>
      <h2 class="text-[1.4rem] font-semibold text-white tracking-[-0.01em]">Two steps left before your first deploy</h2>
      <div class="flex items-center gap-3">
        <div role="progressbar" aria-valuenow="50" aria-valuemin="0" aria-valuemax="100" aria-label="Setup progress" class="h-1.5 flex-1 rounded-full bg-tgx25-line overflow-hidden"><span class="block h-full w-1/2 bg-tgx25-gold"></span></div>
        <span class="text-[0.74rem] tabular-nums text-tgx25-dim">2 / 4</span>
      </div>
    </header>
    <ol class="list-none [counter-reset:tgx25] flex flex-col gap-7 m-0 p-0">
      <li data-done class="[counter-increment:tgx25] relative grid grid-cols-[44px_minmax(0,1fr)] gap-x-3.5 *:col-start-2 before:col-start-1 before:row-start-1 before:content-[counter(tgx25)] before:w-9 before:aspect-square before:rounded-full before:grid before:place-items-center before:font-bold before:text-[0.9rem] before:text-tgx25-dim before:bg-tgx25-bg before:border-2 before:border-tgx25-line before:z-10 after:content-[''] after:absolute after:left-[17px] after:top-10 after:w-0.5 after:h-[calc(100%-36px+1.75rem)] after:bg-tgx25-line last:after:content-none data-done:before:content-['✓'] data-done:before:text-tgx25-bg data-done:before:bg-tgx25-gold data-done:before:border-tgx25-gold data-done:after:bg-tgx25-gold">
        <h3 class="text-[0.95rem] font-semibold text-tgx25-ink pt-1.5">Create your workspace</h3>
        <p class="text-[0.82rem] leading-[1.6] text-tgx25-dim mt-1">northwind-freight · 6 members invited</p>
      </li>
      <li data-done class="[counter-increment:tgx25] relative grid grid-cols-[44px_minmax(0,1fr)] gap-x-3.5 *:col-start-2 before:col-start-1 before:row-start-1 before:content-[counter(tgx25)] before:w-9 before:aspect-square before:rounded-full before:grid before:place-items-center before:font-bold before:text-[0.9rem] before:text-tgx25-dim before:bg-tgx25-bg before:border-2 before:border-tgx25-line before:z-10 after:content-[''] after:absolute after:left-[17px] after:top-10 after:w-0.5 after:h-[calc(100%-36px+1.75rem)] after:bg-tgx25-line last:after:content-none data-done:before:content-['✓'] data-done:before:text-tgx25-bg data-done:before:bg-tgx25-gold data-done:before:border-tgx25-gold data-done:after:bg-tgx25-gold">
        <h3 class="text-[0.95rem] font-semibold text-tgx25-ink pt-1.5">Connect a repository</h3>
        <p class="text-[0.82rem] leading-[1.6] text-tgx25-dim mt-1">GitHub · northwind/freight-api on <code class="font-tgx25-mono text-tgx25-ink">main</code></p>
      </li>
      <li aria-current="step" class="[counter-increment:tgx25] relative grid grid-cols-[44px_minmax(0,1fr)] gap-x-3.5 *:col-start-2 before:col-start-1 before:row-start-1 before:content-[counter(tgx25)] before:w-9 before:aspect-square before:rounded-full before:grid before:place-items-center before:font-bold before:text-[0.9rem] before:text-tgx25-dim before:bg-tgx25-bg before:border-2 before:border-tgx25-line before:z-10 after:content-[''] after:absolute after:left-[17px] after:top-10 after:w-0.5 after:h-[calc(100%-36px+1.75rem)] after:bg-tgx25-line last:after:content-none aria-[current=step]:before:text-tgx25-gold aria-[current=step]:before:border-tgx25-gold aria-[current=step]:before:animate-tgx25-pulse motion-reduce:aria-[current=step]:before:animate-none">
        <h3 class="text-[0.95rem] font-semibold text-tgx25-ink pt-1.5">Configure the build</h3>
        <p class="text-[0.82rem] leading-[1.6] text-tgx25-dim mt-1">Set the build command and the output directory. We detected a Vite project.</p>
        <div class="flex gap-2 mt-3 flex-wrap">
          <button type="button" class="inline-flex items-center min-h-11 px-4 rounded-full bg-tgx25-gold text-tgx25-bg text-[0.82rem] font-semibold cursor-pointer transition-colors hover:bg-tgx25-goldhover focus-visible:outline-2 focus-visible:outline-tgx25-gold focus-visible:outline-offset-2">Use detected settings</button>
          <button type="button" class="inline-flex items-center min-h-11 px-4 rounded-full border border-tgx25-line text-tgx25-ink text-[0.82rem] font-medium cursor-pointer transition-colors hover:bg-tgx25-hover focus-visible:outline-2 focus-visible:outline-tgx25-gold focus-visible:outline-offset-2">Edit manually</button>
        </div>
      </li>
      <li class="[counter-increment:tgx25] relative grid grid-cols-[44px_minmax(0,1fr)] gap-x-3.5 *:col-start-2 before:col-start-1 before:row-start-1 before:content-[counter(tgx25)] before:w-9 before:aspect-square before:rounded-full before:grid before:place-items-center before:font-bold before:text-[0.9rem] before:text-tgx25-dim before:bg-tgx25-bg before:border-2 before:border-tgx25-line before:z-10 after:content-[''] after:absolute after:left-[17px] after:top-10 after:w-0.5 after:h-[calc(100%-36px+1.75rem)] after:bg-tgx25-line last:after:content-none">
        <h3 class="text-[0.95rem] font-semibold text-tgx25-ink pt-1.5">Ship to production</h3>
        <p class="text-[0.82rem] leading-[1.6] text-tgx25-dim mt-1">No line below this step — the <code class="font-tgx25-mono text-tgx25-ink">last:</code> variant suppresses the connector.</p>
      </li>
    </ol>
  </div>
</section>
```
## CSS
```css
@import "tailwindcss";

@theme {
  --color-tgx25-bg: #1d1a14;
  --color-tgx25-bg: oklch(0.2 0.015 85);
  --color-tgx25-line: #4a4234;
  --color-tgx25-line: oklch(0.38 0.03 85);
  --color-tgx25-hover: #2a251c;
  --color-tgx25-hover: oklch(0.26 0.02 85);
  --color-tgx25-gold: #edc167;
  --color-tgx25-gold: oklch(0.83 0.13 85);
  --color-tgx25-goldhover: #f3d089;
  --color-tgx25-goldhover: oklch(0.87 0.11 85);
  --color-tgx25-ink: #f0ebe1;
  --color-tgx25-ink: oklch(0.94 0.01 85);
  --color-tgx25-dim: #bab1a0;
  --color-tgx25-dim: oklch(0.78 0.02 85);
  --font-tgx25-sans: 'Inter Tight', system-ui, sans-serif;
  --font-tgx25-mono: 'JetBrains Mono', ui-monospace, monospace;
  --animate-tgx25-pulse: tgx25-pulse 2s ease-in-out infinite;
}

@keyframes tgx25-pulse {
  50% {
    box-shadow: 0 0 0 6px color-mix(in oklab, var(--color-tgx25-gold) 25%, transparent);
  }
}

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

How this works

Counters heal themselves. counter-reset on the list, counter-increment on the items: delete or reorder a step and the numbering re-flows, which is the whole reason not to hard-code numerals.

State moved from classes to attributes. data-done and aria-current="step" mean the announced state and the painted state are one fact — the upgrade that matters most on a stepper.

Make it yours

  • Advance progress by moving the attributes; colours and connector states follow.
  • Horizontal variant: same counters, grid-flow-col, connector rotated.
  • Slot rich content in the second column — minmax(0,1fr) takes code blocks and screenshots.

Gotchas — read before shipping

  • counter-reset on the LIST, counter-increment on the ITEMS — swapped, you get zeros everywhere.
  • The connector's height must derive from the row gap or the line breaks at each gap.
  • Do not fake this with one absolute full-height line: it overshoots the last step at every content height.

Browser support

ChromeSafariFirefoxEdge
111+16.4+128+111+

Counters predate grid by a decade; the layout is original spec.

Techniques used in this demo

Plain CSSno Tailwind surface

Search CodeFronts

Loading…