Understanding CSS Grid
The first real layout system the web has had.
Why Grid changed what's possible in CSS, the fr unit, and the difference between Grid and Flexbox in one sentence each.
The shape of a Grid.
A grid container has tracks (rows and columns), each with a size. Children place themselves into cells defined by those tracks. display: grid on the parent; grid-template-columns: 200px 1fr 1fr defines three columns; grid-template-rows: auto 1fr auto defines three rows of header/main/footer. Children land in source order unless explicitly placed. That's the whole conceptual model.
The fr unit.
fr means "fraction of the remaining space". 1fr 2fr for two columns: the second column is twice as wide as the first, both filling the container after fixed-width tracks are subtracted. 200px 1fr 1fr reserves 200px for the first column, splits the rest equally between the other two. The fr unit is the single biggest reason Grid is ergonomic — without it, ratio-based layouts needed flexbox or calc gymnastics.
Grid vs Flexbox in one sentence.
Grid is for two-dimensional layout where columns and rows both matter. Flexbox is for one-dimensional layout — a row of items, a column of items — where the other axis is incidental. Page-level layout: Grid. Toolbar of buttons: Flexbox. Card with a horizontal header and stacked content: Flexbox. Photo gallery with rows and columns: Grid. They compose: a Grid cell can be a Flex container, and vice versa.
A worked layout.
A classic "holy grail" — header, sidebar, main, footer. display: grid;
grid-template-columns: 240px 1fr;
grid-template-rows: 64px 1fr 48px;
grid-template-areas:
"header header"
"side main"
"footer footer"; Each child gets grid-area: header, side, etc. Children don't need to be in any particular source order; named areas place them. Resize the window — the 1fr column flexes, the 240px sidebar stays the same. Twelve lines of CSS for a layout that used to need an entire grid framework.
Named-area layout
grid-template-areas + grid-area on children
ASCII-art the layout in the template; assign names per child.
"header header" / "side main" / "footer footer"
= Self-documenting layout CSS
auto-fill vs auto-fit.
For responsive card grids: grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)) creates as many columns as fit at 240px-minimum, fills the rest with empty tracks. auto-fit instead collapses empty tracks so existing items stretch to fill the row. auto-fill keeps the grid; auto-fit stretches the cards. For "however many fit, but always full-width cards", useauto-fit. For "fixed-position grid with empty cells visible", useauto-fill.
Subgrid, the missing piece.
The original Grid spec couldn't propagate column sizes to descendants — every nested grid was independent. Subgrid (shipped in all major browsers by 2023) lets a child grid inherit its parent's tracks. Useful for card layouts where each card has internal grid structure (image, title, body, actions) that should align across cards. Before subgrid: hacks with custom properties. After: grid-template-rows: subgrid.