Overview
grid-template-areas lets you assign human-readable names to grid regions and place items by name rather than by line numbers. This makes layout code self-documenting and easy to restructure at different breakpoints. This card covers the syntax, naming rules, alignment properties, and the canonical layouts that named areas unlock. For utility-class grids in Tailwind see tailwind.
grid-template-areas syntax
Assign area names in the container; use grid-area on items.
.layout {
display: grid;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
grid-template-columns: 240px 1fr;
grid-template-rows: auto 1fr auto;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.footer { grid-area: footer; }| Rule | Detail |
|---|---|
| Each string is one row | Strings separated by whitespace, each defines one row |
| Each word is one column | Words map left-to-right to columns in that row |
| Span by repeating the name | "header header header" spans 3 columns |
| Empty cell | Use . (a dot) for a cell not covered by any named area |
| Names must be valid idents | Letters, digits, -, _; no spaces in a single name |
| Rectangular shape required | A named area must form an unbroken rectangle |
grid-template shorthand
grid-template combines rows, columns, and areas in one declaration.
.layout {
display: grid;
grid-template:
"header header" auto
"sidebar main" 1fr
"footer footer" auto
/ 240px 1fr; /* column sizes after the slash */
}| Shorthand | Equivalent |
|---|---|
grid-template: "a b" 100px / 1fr 2fr | Rows + cols + areas |
grid: "a b" auto / 1fr 2fr | grid also sets implicit tracks |
grid-area: header | Name an item for placement |
grid-area: 2 / 1 / 4 / 3 | Explicit line-based placement (row-start/col-start/row-end/col-end) |
Avoid mixing named and line-based placement in the same layout. Pick one style and stick to it.
Alignment and gaps
| Property | Values | Effect |
|---|---|---|
gap | <row-gap> <col-gap> | Space between tracks; shorthand for row-gap + column-gap |
justify-items | start | end | center | stretch | Align items along the row axis within their cells |
align-items | start | end | center | stretch | Align items along the column axis |
place-items | <align-items> / <justify-items> | Shorthand |
justify-content | start | end | center | space-between | space-around | space-evenly | Distribute columns when tracks don’t fill container |
align-content | same values | Distribute rows when tracks don’t fill container |
place-content | shorthand | Align and justify the whole grid |
justify-self | same as justify-items | Per-item override for row axis |
align-self | same as align-items | Per-item override for column axis |
Responsive overrides
Redefine grid-template-areas inside a media query to change the layout. Item names stay the same.
/* Mobile: single column */
.layout {
display: grid;
grid-template-areas:
"header"
"main"
"sidebar"
"footer";
grid-template-columns: 1fr;
}
/* Tablet and up */
@media (min-width: 768px) {
.layout {
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
grid-template-columns: 240px 1fr;
}
}
/* Desktop */
@media (min-width: 1200px) {
.layout {
grid-template-areas:
"header header header"
"sidebar main aside"
"footer footer footer";
grid-template-columns: 200px 1fr 200px;
}
}Items do not need to change at all; only the container’s template changes.
Common layouts
| Layout name | Template string |
|---|---|
| Holy grail | "header" "sidebar main aside" "footer" with 3 columns |
| Dashboard | "nav nav" "sidebar content" / 60px 1fr |
| Full-bleed header | "header" "content" / 1fr with header spanning full width |
| Card grid (auto-fill) | repeat(auto-fill, minmax(280px, 1fr)) with no named areas |
| Sticky sidebar | "sidebar main" / 280px 1fr + position: sticky on sidebar |
For auto-fill card grids, prefer grid-template-columns alone without named areas; the implicit placement algorithm handles wrapping automatically.
Common gotchas
- A named area must be a perfect rectangle. An L-shaped or T-shaped region (e.g.,
"a b" "a a") is invalid and falls back to the initial value. grid-areaon an item overrides all four placement lines at once. Setting it after individualgrid-roworgrid-columndeclarations discards those declarations.gapdoes not collapse. Addinggap: 1rembetween a header and content that already havemargin-bottomstacks both gaps.- Items placed outside named areas (via line numbers or auto placement) can overlap named-area items without a
z-index. grid-template-areaswith a dot.cell does not prevent auto-placed items from filling that cell. Usegrid-column: span 1and explicit placement to prevent it.- The
frunit distributes free space after fixed tracks and gaps are subtracted.1frin a container withgap: 24pxis smaller than1frin the same container without a gap.