Glossary

CSS Grid

CSS Grid is a two-dimensional layout system in CSS that lets you place the children of an element into rows and columns at the same time. You turn it on with display: grid on a container, and it is specified in the W3C CSS Grid Layout Module, Level 1, with Level 2 adding subgrid. The line most people search for is grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)).

How it works

The element with display: grid is the grid container, and its direct children become grid items. You define tracks (rows and columns) on the container and the browser places items into the resulting cells. Flexbox lays out one axis at a time, while Grid controls rows and columns together.

  • grid-template-columns and grid-template-rows: list the track sizes, for example 200px 1fr or repeat(3, 1fr).
  • fr unit: a flexible length that takes a fraction of the leftover space in the container after fixed tracks and gaps.
  • gap, row-gap, column-gap: the gutters between tracks. They replaced the older grid-gap names.
  • minmax(min, max): a track size range.
  • repeat(auto-fill | auto-fit, size): creates as many tracks as fit.
  • grid-auto-flow: the default is row. Items beyond the explicit tracks create implicit rows sized by grid-auto-rows, which defaults to auto.
  • grid-template-areas and grid-area: name regions and place items by name.
.g { display: grid; width: 700px; gap: 10px; }
#a { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
#b { grid-template-columns: repeat(auto-fit,  minmax(150px, 1fr)); }
#c { grid-template-columns: 1fr 2fr 1fr; }

Computed grid-template-columns in headless Chromium 141 (a and b hold 2 items, c holds 3):

a  167.5px 167.5px 167.5px 167.5px
b  345px 345px 0px 0px
c  170px 340px 170px

In a, four columns fit: 4 x 150px plus 3 x 10px gaps is 630px, and a fifth would need 790px. The leftover 70px is shared by the four columns. In b, the two empty tracks collapse to 0px and the two items fill the row.

What is the difference between auto-fill and auto-fit?

Both create as many columns as fit, and the only difference is what happens to empty tracks. With auto-fill the empty tracks stay in the grid and keep taking space, so the items occupy only the first columns. With auto-fit, the empty tracks collapse to 0px and the remaining items stretch to fill the row. The two behave the same once the row is full.

What does 1fr mean in CSS Grid?

1fr means one share of the free space in the grid container after fixed-size tracks and gaps are subtracted. In 1fr 2fr 1fr on a 700px container with two 10px gaps, 680px is shared in the ratio 1 to 2 to 1, which gives 170px, 340px and 170px. Outside minmax(), the spec treats 1fr as minmax(auto, 1fr), so a bare 1fr cannot shrink below its content. That causes overflow.

Common pitfalls

  • 1fr overflows on long content: a 1fr track will not shrink below its minimum content size. In a test with 1fr 1fr, a 300px container and a 10px gap, a nowrap item holding 30 W characters forced the tracks to 8px and about 453px. Use minmax(0, 1fr), which gave two 145px columns.
  • Using auto-fill when you meant auto-fit: with few items, auto-fill leaves empty columns and the items do not stretch. Use auto-fit to stretch them.
  • Old property names: grid-gap, grid-row-gap and grid-column-gap were replaced by gap, row-gap and column-gap, which are now defined in CSS Box Alignment.
  • Forgetting the implicit grid: items placed outside the declared tracks get rows sized auto. Set grid-auto-rows to control them.
  • Expecting grid to inherit into children: only direct children are grid items. A nested grid needs its own display: grid, or subgrid from Level 2.

Related terms

  • Flexbox — the one-dimensional layout system that Grid complements
  • DOM — the element tree whose parent becomes the grid container and whose direct children become grid items

See also