Skip to content
AgileLogics
7 min read

CSS Grid Basics

Prerequisites: Flexbox in depth

CSS Grid lays out items in rows and columns at the same time.

.layout {
  display: grid;
  grid-template-columns: 250px 1fr;
  grid-template-rows: auto 1fr auto;
  gap: 1rem;
  min-height: 100dvh;
}
  • grid-template-columns defines column tracks: a 250px sidebar and a flexible main column.
  • The fr unit is a fraction of the remaining free space.
  • gap sets space between tracks (row-gap, column-gap separately).
  • Items fill cells in order, left to right, top to bottom, unless you place them.

Track sizes

<style>
  .g { display: grid; width: 610px; grid-template-columns: 100px 1fr 2fr; gap: 30px; }
  .g > div { height: 40px; }
</style>
<div class="g"><div>A</div><div>B</div><div>C</div><div>D</div></div>
<script>
  const g = document.querySelector(".g");
  console.log("columns:", getComputedStyle(g).gridTemplateColumns);
  const box = g.getBoundingClientRect();
  for (const el of g.children) {
    const r = el.getBoundingClientRect();
    console.log(el.textContent, "x:", r.left - box.left, "y:", Math.round(r.top - box.top), "w:", r.width);
  }
</script>
columns: 100px 150px 300px
A x: 0 y: 0 w: 100
B x: 130 y: 0 w: 150
C x: 310 y: 0 w: 300
D x: 0 y: 70 w: 100

610px − 100px − 2 × 30px gaps leaves 450px, split 1 : 2 into 150px and 300px. The fourth item wrapped into a new row, created automatically (an implicit row).

repeat() and minmax()

.three-columns { grid-template-columns: repeat(3, 1fr); }
.cards { grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); }

The second line is the most useful line of CSS Grid: as many columns as fit, each at least 16rem wide, stretching to fill the row. Cards reflow from one column on a phone to four on a wide screen — no media queries.

  • auto-fit collapses empty tracks, so a few items stretch across the row; auto-fill keeps empty tracks, so items keep their size.
  • minmax(min, max) gives a track a size range.

Placing items

Grid lines are numbered from 1; negative numbers count from the end:

.header { grid-column: 1 / -1; }
.feature { grid-column: span 2; grid-row: span 2; }
.sidebar { grid-column: 1; grid-row: 2 / 4; }

1 / -1 spans from the first to the last line — a full-width header.

Alignment

justify-items / align-items align items inside their cells (the default is stretch); place-items: center does both. justify-content and align-content position the whole grid when it's smaller than the container. The shortest way to center one thing:

.center { display: grid; place-items: center; }

Use the Grid inspector in DevTools to see line numbers and track sizes.

Practice

Create a photo grid with columns at least 200px wide that fill the row, 12px gaps, and a .wide class that makes an item span two columns.

Show solution
.photos {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 12px;
}

.photos .wide {
  grid-column: span 2;
}