Grid Utilities

Tailwind CSS · Lesson 12 of 27 6 min read Updated

CSS Grid lays things out in two dimensions at once: rows and columns that line up with each other. Card galleries, dashboards, photo walls, pricing tables and whole page layouts are all natural grids. Tailwind makes the common cases one or two classes long.

This lesson covers the Tailwind classes; for the CSS concepts behind them see CSS Grid Basics. You will build a dashboard with tiles of different sizes, a gallery that fits as many columns as the screen allows, and product cards whose parts line up across the row with subgrid.

Columns and gaps

Put grid on the parent and choose how many columns with grid-cols-*. Children fill the cells from left to right, wrapping to a new row automatically.

ClassCSS
griddisplay: grid
grid-cols-3grid-template-columns: repeat(3, minmax(0, 1fr))
gap-4, gap-x-6, gap-y-2Space between cells
grid-rows-2Two equal rows

grid-cols-3 makes three equal columns that share the width. The minmax(0, 1fr) part means a long word or wide image cannot make one column wider than the others. Any number works: grid-cols-7 is perfect for a calendar month.

Spanning cells

Children can stretch across several columns or rows:

  • col-span-2 covers two columns; col-span-full covers the whole row.
  • row-span-2 covers two rows.
  • col-start-2 and col-end-4 place an item between exact grid lines.
HTMLTry it yourself
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Dashboard grid</title>
  <script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4.3.3"></script>
</head>
<body class="bg-slate-100 p-6">
  <div class="grid max-w-3xl grid-cols-4 gap-4">
    <div class="col-span-full rounded-xl bg-slate-900 p-4 text-white">Shop dashboard: Meera Sweets, Jaipur</div>
    <div class="col-span-2 row-span-2 rounded-xl bg-white p-4">
      <p class="text-sm text-slate-500">Today's sales</p>
      <p class="text-4xl font-bold">₹48,250</p>
    </div>
    <div class="rounded-xl bg-white p-4"><p class="text-sm text-slate-500">Orders</p><p class="text-2xl font-bold">132</p></div>
    <div class="rounded-xl bg-white p-4"><p class="text-sm text-slate-500">Returns</p><p class="text-2xl font-bold">2</p></div>
    <div class="col-span-2 rounded-xl bg-amber-100 p-4">Kaju katli is running low: 4 kg left.</div>
  </div>
</body>
</html>

The sales tile spans two columns and two rows, and the grid fits the smaller tiles around it. You did not have to calculate any widths.

Custom column sizes

Equal columns are not always right. For a sidebar layout or a row with a label, a flexible middle and a button, write the track sizes yourself with an arbitrary value. Use underscores for spaces:

HTML
<!-- Fixed 16rem sidebar, flexible main area -->
<div class="grid grid-cols-[16rem_1fr] gap-6">...</div>

<!-- Icon, flexible text, price that hugs its content -->
<li class="grid grid-cols-[auto_1fr_auto] items-center gap-3">...</li>

1fr means "one share of the remaining space", and auto means "as wide as the content". You will learn more about square-bracket values in Arbitrary Values & Properties.

The most useful arbitrary grid is the auto-fill pattern. Instead of saying "three columns", you say "as many columns as fit, each at least 12rem wide". The grid then adapts to any screen without a single breakpoint.

HTMLTry it yourself
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Auto-fill gallery</title>
  <script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4.3.3"></script>
</head>
<body class="p-6">
  <h2 class="mb-4 text-xl font-bold">College fest photos</h2>
  <div class="grid grid-cols-[repeat(auto-fill,minmax(12rem,1fr))] gap-3">
    <img src="https://course.ethicscomputer.in/assets/samples/landscape.svg" alt="Stage at night" class="aspect-video w-full rounded-lg object-cover">
    <img src="https://course.ethicscomputer.in/assets/samples/landscape.svg" alt="Dance team" class="aspect-video w-full rounded-lg object-cover">
    <img src="https://course.ethicscomputer.in/assets/samples/landscape.svg" alt="Food stalls" class="aspect-video w-full rounded-lg object-cover">
    <img src="https://course.ethicscomputer.in/assets/samples/landscape.svg" alt="Robotics contest" class="aspect-video w-full rounded-lg object-cover">
    <img src="https://course.ethicscomputer.in/assets/samples/landscape.svg" alt="Prize ceremony" class="aspect-video w-full rounded-lg object-cover">
    <img src="https://course.ethicscomputer.in/assets/samples/landscape.svg" alt="Group photo" class="aspect-video w-full rounded-lg object-cover">
  </div>
</body>
</html>

Drag the editor wider and narrower: the gallery switches between one, two, three or more columns on its own.

Rows, flow and alignment

  • grid-rows-3 sets three equal rows; auto-rows-fr makes every automatically created row the same height.
  • grid-flow-dense lets later small items fill holes left by big items earlier in the grid.
  • place-items-center centres every item inside its cell. You can also use justify-items-* and items-* separately, or justify-self-* and self-* on one item.

A one-line way to centre anything on a page is grid min-h-svh place-items-center on the parent.

Advanced: lining up cards with subgrid

When cards in a row have titles of different lengths, their prices and buttons end up at different heights. Subgrid fixes this: each card spans several rows of the parent grid and uses the parent's row tracks for its own children, so the same part of every card shares a row.

HTMLTry it yourself
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Subgrid cards</title>
  <script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4.3.3"></script>
</head>
<body class="bg-slate-100 p-6">
  <div class="grid max-w-3xl gap-x-4 sm:grid-cols-3">
    <article class="row-span-3 grid grid-rows-subgrid gap-2 rounded-xl bg-white p-4">
      <h3 class="font-semibold">Steel water bottle</h3>
      <p class="text-2xl font-bold">₹399</p>
      <button class="rounded-lg bg-sky-600 py-2 text-white">Add</button>
    </article>
    <article class="row-span-3 grid grid-rows-subgrid gap-2 rounded-xl bg-white p-4">
      <h3 class="font-semibold">Insulated lunch box with three compartments and spoon</h3>
      <p class="text-2xl font-bold">₹749</p>
      <button class="rounded-lg bg-sky-600 py-2 text-white">Add</button>
    </article>
    <article class="row-span-3 grid grid-rows-subgrid gap-2 rounded-xl bg-white p-4">
      <h3 class="font-semibold">School bag</h3>
      <p class="text-2xl font-bold">₹1,299</p>
      <button class="rounded-lg bg-sky-600 py-2 text-white">Add</button>
    </article>
  </div>
</body>
</html>

Every card has row-span-3 grid grid-rows-subgrid, so its title, price and button sit in the parent's three shared rows. All three prices line up even though the middle title takes three lines. Remove grid-rows-subgrid to see the difference. Subgrid works in all current major browsers; see Subgrid.

Grid or Flexbox?

  • Use Flexbox for one direction: a row of buttons, a navbar, an icon with text, a stack of form fields.
  • Use Grid when items must line up in both directions: galleries, card lists, dashboards, page layouts.
  • They mix freely. A grid of cards where each card uses flex inside is very common.

Common mistakes

  • Forgetting grid. grid-cols-3 does nothing unless the parent also has grid.
  • Fixed column counts on phones. grid-cols-4 squeezes four columns onto a small screen. Start with one column and add more at breakpoints (sm:grid-cols-2 lg:grid-cols-4), or use auto-fill.
  • Spaces in arbitrary values. grid-cols-[200px 1fr] is broken into two classes. Write grid-cols-[200px_1fr].
  • Spanning more columns than exist. col-span-4 in a three-column grid creates an extra column and breaks the layout.

Key points

  • grid grid-cols-3 gap-4 makes three equal columns with gaps; any number of columns works.
  • col-span-*, row-span-* and col-span-full make items cover several cells.
  • Write custom tracks with arbitrary values such as grid-cols-[16rem_1fr], using underscores for spaces.
  • grid-cols-[repeat(auto-fill,minmax(12rem,1fr))] makes a gallery that adapts without breakpoints.
  • place-items-center centres items in their cells; grid-rows-subgrid lines up parts of cards across a row.

Exercise

Create a simple timetable for a coaching class in Kochi with five columns: a time column and Monday to Thursday. Add a header row, and two class rows. Make the "Lunch break" cell span all four day columns.

Show solution
HTML
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Timetable</title>
  <script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4.3.3"></script>
</head>
<body class="p-6">
  <div class="grid max-w-2xl grid-cols-5 gap-1 text-center text-sm">
    <div class="bg-slate-800 p-2 text-white">Time</div>
    <div class="bg-slate-800 p-2 text-white">Mon</div>
    <div class="bg-slate-800 p-2 text-white">Tue</div>
    <div class="bg-slate-800 p-2 text-white">Wed</div>
    <div class="bg-slate-800 p-2 text-white">Thu</div>
    <div class="bg-slate-100 p-2">10:00</div>
    <div class="bg-sky-100 p-2">Maths</div>
    <div class="bg-sky-100 p-2">Physics</div>
    <div class="bg-sky-100 p-2">Maths</div>
    <div class="bg-sky-100 p-2">Chemistry</div>
    <div class="bg-slate-100 p-2">12:30</div>
    <div class="col-span-4 bg-amber-100 p-2">Lunch break</div>
  </div>
</body>
</html>

grid-cols-5 creates the five columns and col-span-4 stretches the lunch cell across the four day columns.

Quick Quiz

1. What does grid-cols-3 create?

2. Which class makes an item stretch across every column of its grid?

3. How do you write a grid with a 16rem first column and a flexible second column?

4. What problem does grid-rows-subgrid solve in a row of cards?

Learn Tailwind CSS with a mentor

Free lessons get you started. Our Full Stack Web Development training adds real projects and code reviews from working developers.

  • Project-based learning
  • Mentor code reviews
  • Free counselling call