CSS Grid-Template-Areas: Named Layouts Explained
grid-template-areas lets you name grid regions and place items by name instead of row and column numbers, turning your CSS into a visual map of the layout.
grid-template-areas is a CSS Grid property that lets you name regions of a layout as ASCII-art strings, then place child elements into those regions by name instead of counting rows and columns. It turns a grid definition into something you can read at a glance — the CSS itself looks like a diagram of the page.
The basic syntax
A grid layout normally requires you to track numeric line positions: grid-column: 2 / 4, grid-row: 1 / 3. That works, but it’s not self-documenting — you have to mentally render the grid to know what a rule does. Named areas fix that by giving each cell a label directly in the container:
.layout {
display: grid;
grid-template-columns: 200px 1fr;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"sidebar header"
"sidebar main"
"sidebar footer";
}
.header { grid-area: header; }
.main { grid-area: main; }
.sidebar { grid-area: sidebar; }
.footer { grid-area: footer; }
Each quoted string is one row; each word inside it is one column’s area name. Repeating a name across adjacent cells — as sidebar does across three rows — makes that item span all of them. The visual shape of the strings mirrors the visual shape of the page, which is the whole appeal: you can see the layout by reading the property.
Rules for valid area declarations
The browser enforces a few constraints so the areas stay well-formed:
- Every row string must have the same number of columns as every other row.
- A named area must form a single rectangle. You cannot write
"a a" "b a"— that makesaan L-shape, which is invalid and gets ignored. - Use a period (
.) to mark a cell as empty — no item is placed there, and no background or border applies unless you style the grid container itself. - Named lines are generated automatically: an area called
headerproduces implicit line namesheader-startandheader-end, which you can reference fromgrid-roworgrid-columnon other elements if needed.
Combining areas with responsive layouts
The biggest practical win is at breakpoints. Reflowing a layout with numeric line positions means recalculating every item’s row and column span. With named areas, you just redraw the map:
.layout {
grid-template-columns: 1fr;
grid-template-areas:
"header"
"main"
"sidebar"
"footer";
}
@media (min-width: 800px) {
.layout {
grid-template-columns: 200px 1fr;
grid-template-areas:
"sidebar header"
"sidebar main"
"sidebar footer";
}
}
The child rules (grid-area: header, and so on) never change — only the container’s map does. This pairs well with container queries when the reflow should respond to a parent’s size rather than the viewport, and with CSS Grid vs Flexbox if you’re still deciding which layout model fits a given component.
grid-template-areas vs manual line placement
| Named areas | Line-number placement | |
|---|---|---|
| Readability | Layout shape visible in the CSS | Requires mental math |
| Reordering | Redraw the map, one property | Recompute every affected line |
| Non-rectangular spans | Not supported | Fully flexible |
| Empty cells | . placeholder | Just leave a line range unused |
| Best for | Page-level and component-level layout with a clear shape | Dense, irregular, or programmatically generated grids |
Named areas are not a replacement for line-based placement — they’re a more readable notation for the common case where a layout has a fixed, describable shape. For irregular or auto-placed dense grids (image galleries, masonry-style layouts), line numbers or grid-auto-flow: dense still do more of the work.
Working with subgrid
When a nested component needs to align its own internal columns to the parent’s grid — rather than just occupying one named area — CSS subgrid is the tool for that. grid-template-areas places a box into a slot; subgrid lets that box’s children inherit the outer grid’s tracks so everything lines up across component boundaries. The two features solve different problems and combine cleanly: use named areas for the page skeleton, subgrid for components that need to align within a named region.
Debugging areas
Most browser devtools have a dedicated grid inspector that overlays line numbers, track sizes, and area names directly on the rendered page — toggle it from the badge next to any element with display: grid in the elements panel. It’s the fastest way to confirm an area is the rectangle you think it is, especially when a typo in one row string silently breaks the whole map (a mismatched column count invalidates the entire grid-template-areas declaration, and the browser falls back to default placement without an error in the console).
Custom properties can also make area names easier to maintain across a large stylesheet — see CSS custom properties if you want to centralize breakpoint-specific layout maps rather than repeating full string blocks in every media query.
The takeaway
grid-template-areas trades a small amount of flexibility for a large amount of readability: layouts become self-documenting ASCII maps instead of line-number arithmetic. It shines for page shells and components with a clear, nameable structure, and it pairs naturally with subgrid for nested alignment and with media queries for responsive reflows. For irregular or auto-generated grids, fall back to numeric line placement — but for the layouts most sites actually ship, named areas are usually the clearer choice.
Tagged
Keep reading
Takina · · 4 min read HTML details and summary Elements Explained
The HTML details and summary elements build native disclosure widgets and accordions with no JavaScript. How they work, how to style them, and pitfalls.
Takina · · 4 min read CSS pointer-events Explained: Click-Through and Its Traps
CSS pointer-events: none makes an element ignore mouse, touch, and pen input so clicks pass through. How it works, good uses, and why it doesn't disable.
Takina · · 4 min read CSS @starting-style Explained: Entry Transitions in CSS
CSS @starting-style defines an element's before-state on first render, so transitions can animate elements as they appear, even from display: none.