CSS Grid

CSS · Practical · 15 min

Grid makes page layouts, galleries and dashboards that used to need frameworks a few lines of CSS.

display: grid lays children out in rows and columns at once.

Defining tracks: grid-template-columns: 200px 1fr 1fr makes three columns. The fr unit takes a fraction of the remaining free space. repeat(3, 1fr) is three equal columns, and minmax(200px, 1fr) is a track that's at least 200px and grows to share space. Rows are created automatically as needed; grid-auto-rows sizes them. gap spaces rows and columns.

The responsive-gallery one-liner needs no media queries: grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)) fits as many 220px+ columns as there's room for, and stretches them to fill the row.

Placing items: by default items fill cells in order. To place explicitly, use line numbers: grid-column: 1 / 3 spans from line 1 to line 3, or grid-column: span 2. Negative numbers count from the end, so 1 / -1 spans the full width.

Named areas make page layouts readable:

grid-template-areas: "head head" "side main" "foot foot";

then grid-area: main on a child. Changing the template in a media query rearranges the whole layout.

Alignment works like flexbox: justify-items/align-items within cells, and place-items: center for both. Choose grid when you think in rows and columns, flexbox when content in one line should decide its own size.

Example

/* <div class="page"><header/><aside/><main/><footer/></div> */
.page {
  display: grid;
  grid-template-columns: 240px 1fr;
  grid-template-rows: auto 1fr auto;
  grid-template-areas:
    "head head"
    "side main"
    "foot foot";
  min-height: 100dvh;
  gap: 1rem;
}
.page > header { grid-area: head; }
.page > aside  { grid-area: side; }
.page > main   { grid-area: main; }
.page > footer { grid-area: foot; }

.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));  /* responsive */
  gap: 12px;
}
.gallery .featured { grid-column: span 2; }

Remember

  • fr shares free space; minmax() sets a range
  • repeat(auto-fit, minmax(X, 1fr)) is a responsive grid with no media queries
  • grid-column: 1 / -1 spans the full width
  • Named areas make layouts readable and easy to rearrange

Watch out for

  • Using grid-column: 1 / 3 and expecting it to span three columns; it spans lines 1 to 3, two columns.

Check yourself

  1. grid-template-columns: 100px 1fr 2fr in a 400px wide container with no gap. How wide is the last column?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: developer.mozilla.org/en-US/docs/Web/CSS/Guides/Grid_layout/Basic_concepts