Learning LibraryWebsite Development LibraryTeens

CSS Grid: rows and columns in one step

A gallery of cards isn't a single row. It's rows and columns, with every card the same width. Grid handles both directions with a couple of classes.

The big idea

A grid container divides its space into columns and places its children into the resulting cells, row by row.

See it in code

1The basics

grid makes the container a grid. grid-cols-3 asks for three equal columns, and gap-4 spaces the cells in both directions:

html
<div class="grid grid-cols-3 gap-4 p-6">
  <div class="rounded-xl bg-white/5 p-6">Perseverance</div>
  <div class="rounded-xl bg-white/5 p-6">Webb</div>
  <div class="rounded-xl bg-white/5 p-6">Juno</div>
</div>
Three cards, three columns:

You never set a card's width. The grid divides the available space into three equal tracks, and each child takes one.

2A step further

Add a fourth child and it wraps to a new row by itself. You describe the columns; the grid creates as many rows as it needs:

html
<div class="grid grid-cols-3 gap-4 p-6">
  <div class="rounded-xl bg-white/5 p-6">Perseverance</div>
  <div class="rounded-xl bg-white/5 p-6">Webb</div>
  <div class="rounded-xl bg-white/5 p-6">Juno</div>
  <div class="rounded-xl bg-white/5 p-6">Cassini</div>
</div>
Four cards in a three-column grid:

The fourth card is exactly as wide as the others, lined up under the first. Adding content never requires rethinking the layout.

3On COSMOS

col-span-2 makes one child take two columns. The other children flow around it automatically:

html
<div class="grid grid-cols-3 gap-4 p-6">
  <article class="col-span-2 rounded-xl border border-violet-400/40 bg-violet-500/10 p-6">
    <p class="text-xs uppercase tracking-widest text-violet-300">Featured</p>
    <h3 class="mt-1 text-xl font-bold">Juno</h3>
    <p class="mt-1 text-sm text-slate-300">Orbiting Jupiter since 2016 and mapping its storms.</p>
  </article>
  <article class="rounded-xl bg-white/5 p-6"><h3 class="font-bold">Webb</h3></article>
  <article class="rounded-xl bg-white/5 p-6"><h3 class="font-bold">Cassini</h3></article>
  <article class="rounded-xl bg-white/5 p-6"><h3 class="font-bold">Apollo 8</h3></article>
</div>
A featured mission, twice as wide:

The featured card and one normal card fill the three columns of row one. The remaining two start row two, leaving one cell empty.

The same idea, everywhere

Two-dimensional layout is the grid's whole purpose: photo galleries, dashboards, calendars, pricing tables, the tiles on a phone's home screen.

Try it yourself

Move col-span-2 from Juno to the last card and predict where the empty cell ends up. Then change grid-cols-3 to grid-cols-2 and re-read the layout.

The common mistake

A typo in the columns class. grid-col-3, without the s, is ignored, and a grid with no column definition is a single column: every card stacks full width.

What it unlocks

Grid and flexbox are partners: grid for the page's cells, flex inside each one. To change the number of columns by screen size, add responsive prefixes.