Two axes at once
Flexbox lays things along one axis and wraps when it runs out. Grid defines a structure — rows and columns — and places items into it. When the alignment has to hold in both directions, grid is the tool.
.grid {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 20px;
}
fr
fr is a share of the space left over after gaps and fixed tracks are taken out. 1fr 2fr gives the second track twice the leftover. It only exists in grid track sizing.
.layout {
display: grid;
grid-template-columns: 260px 1fr; /* fixed, then everything else */
gap: 32px;
}
1fr is really minmax(auto, 1fr), so a track will not shrink below its content — one long word or a wide table blows the layout out. Write minmax(0, 1fr) when the content might be wide.
repeat, minmax, auto-fit
Those four lines replace a stack of breakpoints. With two cards, auto-fit gives two wide ones; auto-fill gives two narrow ones and empty space.
repeat(3, 1fr)— three equal tracks.minmax(240px, 1fr)— at least 240, otherwise a share of the space.auto-fill— make as many tracks as fit, leaving empty ones.auto-fit— the same, then collapse the empty ones so the items stretch.
.cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
gap: 20px;
}
Rows
Tracks you define are the explicit grid. Items that go past it create implicit tracks, sized by grid-auto-rows or grid-auto-columns.
.grid {
display: grid;
grid-template-rows: auto 1fr auto; /* header, body, footer */
grid-auto-rows: minmax(120px, auto); /* any row beyond the template */
min-height: 100svh;
}
Placing an item
Grid lines are numbered from 1, and negative numbers count from the end. 1 / -1 is the one to remember: full width, however many columns there turn out to be.
.feature {
grid-column: 1 / 3; /* from line 1 to line 3 — two columns */
grid-column: span 2; /* two columns, wherever it lands */
grid-column: 1 / -1; /* the whole width, whatever the count */
grid-row: 2 / 4;
}
Named areas
The rearrangement at the breakpoint is four words. Note that side moves below main visually while staying before it in the DOM — the same caveat as flex order applies, so use it only where the reading order still makes sense.
.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: 100svh;
gap: 24px;
}
.page > header { grid-area: head; }
.page > aside { grid-area: side; }
.page > main { grid-area: main; }
.page > footer { grid-area: foot; }
@media (max-width: 720px) {
.page {
grid-template-columns: 1fr;
grid-template-areas: "head" "main" "side" "foot";
}
}
Alignment
.centre {
display: grid;
place-items: center;
min-height: 100svh;
}
| Property | Aligns |
|---|---|
justify-items / justify-self | Items within their cell, along the inline (row) axis. |
align-items / align-self | Items within their cell, along the block (column) axis. |
justify-content | The whole grid in the container, horizontally — when the tracks do not fill it. |
align-content | The whole grid vertically. |
place-items: center | Shorthand for both item axes. |
Overlap
Two grid items placed in the same cell overlap, in DOM order, and z-index orders them. That makes grid the cleanest way to stack things — a caption over an image, a gradient over a video — without position: absolute and its guesswork.
.hero {
display: grid;
}
.hero > * {
grid-area: 1 / 1; /* everything in the same cell */
}
.hero .caption {
align-self: end;
z-index: 1;
}
Subgrid
subgrid lets a child use its parent's tracks instead of its own. It solves the problem cards have had forever: three cards whose titles, text and buttons all line up with each other, however long the text is.
.deck {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
grid-template-rows: auto 1fr auto;
gap: 20px;
}
.card {
display: grid;
grid-row: span 3;
grid-template-rows: subgrid; /* take the deck's three rows */
}
Grid or flex?
- Grid when you know the structure: a page layout, a card deck, a form with labels and fields aligned, anything where both axes matter.
- Flex when the content decides: a row of buttons, a toolbar, a tag list, anything that is "line these up and share the space".
- They nest happily. A grid of cards, each of which is a flex column, is the most common combination there is.