Course outline · 0% complete

0/30 lessons0%

Course overview →

CSS grid basics

lesson 7-1 · ~9 min · 21/30

From lesson 6-1, justify-content aligns flex items along the main axis.

PropertyAxis
justify-contentmain, always
align-itemscross

That model stays useful here, because grid reuses the idea while controlling two axes at once.

Rows and columns at once

Any app used daily, whether a photo gallery, a dashboard of stat cards, or a page with a sidebar, is rows and columns that stay aligned with each other. Flexbox lays items out along one axis, so aligning across rows required hacks. Grid controls two.

.gallery {
  display: grid;
  grid-template-columns: 200px 1fr 1fr;
  gap: 16px;
}
Track valueMeaning
200pxa fixed column
1frone fraction of the free space
2frtwice the share of a 1fr track

grid-template-columns defines the column tracks, here a fixed 200px column followed by two flexible ones.

fr is a new unit meaning one fraction of the free space, so 1fr 1fr splits the leftover equally and 2fr 1fr splits it 2 to 1, just as flex-grow did in lesson 6-2.

Children fill the cells automatically, left to right, wrapping into new rows as needed. The shorthand typed constantly is grid-template-columns: repeat(3, 1fr);, which makes three equal columns.

200px1fr1frfixedflexibleflexiblecellcellcell
grid-template-columns: 200px 1fr 1fr. The first track is fixed, and the two gold fr tracks share whatever space remains.

Spanning and placing

Any grid child can claim more than one cell.

.featured {
  grid-column: 1 / 3; /* start at line 1, end at line 3: spans 2 columns */
}
.sidebar {
  grid-row: 1 / 4;    /* spans 3 rows */
}

Grid counts the lines between tracks, starting at 1, so three columns have four lines.

TracksLines1 / 3 spans
3 columns4the first two columns
3 rows4the first two rows

So grid-column: 1 / 3 reads as start at line 1 and end at line 3, which is two tracks rather than three.

Choosing between the two tools is straightforward. Grid handles the page-level skeleton, meaning header, sidebar, content, and galleries, and flexbox handles one-dimensional rows inside it, meaning navbars, button groups, and card internals.

They compose, since a grid cell often contains a flex container, exactly like the header from lesson 6-3.

Splitting free space between fr tracks

With grid-template-columns: 1fr 2fr and 300px of free space, the second column is 200px.

The free space splits into 1 + 2 = 3 shares of 100px each, and the second column takes 2 shares.

TrackSharesWidth
1fr1100px
2fr2200px

The arithmetic is always the same, namely total shares first, then one share, then each track. Fixed tracks are subtracted before any of this, which is why a 200px 1fr 1fr grid divides only what remains after the fixed column.

A gallery with one wide tile

Three equal columns, plus a single item that opts out of the pattern to span two of them.

CSS

.gallery {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
}

.featured {
  grid-column: 1 / 3;
}

.tile {
  background: #d4af37;
  border-radius: 8px;
  min-height: 90px;
  display: flex;
  justify-content: center;
  align-items: center;
  font-family: sans-serif;
  font-size: 1.5rem;
}
DeclarationLevelEffect
repeat(3, 1fr)containerthree equal fraction columns
gap: 12pxcontainerspace between cells
grid-column: 1 / 3one itemspans the first two columns

repeat(3, 1fr) is the shorthand for three equal fraction columns, and grid-column counts lines rather than tracks, so 1 / 3 spans the first two columns.

The tiles are themselves flex containers, centering their own labels. That is the grid-plus-flex composition in a single short stylesheet.

The fraction unit

The unit meaning one share of a grid's free space is fr, the fraction unit.

After fixed tracks take their space, the remaining free space is divided among fr tracks in proportion to their numbers.

TemplateFixedFree space split
200px 1fr 1fr200pxequally in two
1fr 2frnone1 to 2

The first row is the example from earlier in the lesson. Because fr describes a share rather than a size, a grid built from it never overflows the way a row of fixed pixel widths eventually does.