ToolNest logoToolNest.

grid-template-areas Explained

grid-template-areas lets you draw your layout with words: name each region of the page — header, sidebar, main, footer — then arrange those names in a text map to place them. Prototype any layout with our free CSS grid generator; the syntax, the rules, and the gotchas are below.

The syntax: drawing layouts with words

grid-template-areas turns a CSS declaration into a visual map of your page. You name each region with grid-area, then draw the map as quoted strings — one string per row, with each name occupying one cell: grid-template-areas: 'header header' 'sidebar main' 'footer footer'; paired with grid-template-columns: 280px 1fr; and grid-template-rows: 72px 1fr 64px;. Every string must contain the same number of cells, and whitespace between names defines column boundaries, so indentation actually matters for readability: align the quotes and the map reads like a wireframe. Repeating a name across adjacent cells is what makes a region span — 'header header' means the header covers both columns, no span declarations needed. A period . marks an empty cell, which is handy for asymmetric layouts: 'header header header' '. main main' 'footer footer footer'; leaves the first cell of row two blank, so the main content starts one column in. Children are placed with grid-area: header; on the matching element — no line numbers, no remembering that the sidebar starts at line 1 and ends at line 2. For a 1200-pixel container this produces a 280-pixel sidebar and a 920-pixel main column automatically, since 1fr takes whatever space remains. The ASCII-art quality is the point: you can read the layout at a glance, and so can the next developer.

Naming rules and the rectangular rule

Two hard rules govern area names. First, every row must declare the same number of columns — 'header header' next to 'sidebar' is invalid and the entire declaration is thrown out, silently breaking your layout. Second, and the one that bites everyone: a named area must form a single rectangle. You cannot make an L-shaped area — 'header header' on row one and 'header sidebar' on row two fails, because the header cells are not a contiguous rectangle. Browsers simply ignore the invalid template, which makes this bug confusing: the layout falls back to auto-placement with no console error. Names themselves are custom identifiers: lowercase letters, hyphens, and underscores are safe; start with a letter, avoid spaces (spaces separate cells), and steer clear of reserved words. Each name you use in the map must have a corresponding grid-area element — a name with no matching element creates an empty region, which is legal but usually a typo. Conversely, an element with a grid-area name that does not appear in the map gets auto-placed, which is legal but usually a surprise. The rectangle rule is worth internalizing because it shapes how you design: if a region needs to be L-shaped, split it into two rectangles or restructure. Most debuggers show the area outlines in the grid overlay, so inspect the named regions visually before assuming the syntax is wrong.

The holy grail in six lines

The classic 'holy grail' layout — header, three columns (nav, content, aside), footer — is the poster child for template areas. Full declaration: .page { display: grid; grid-template-columns: 200px 1fr 220px; grid-template-rows: 64px 1fr 56px; grid-template-areas: 'header header header' 'nav content aside' 'footer footer footer'; min-height: 100vh; gap: 0; } Then header { grid-area: header; } nav { grid-area: nav; } and so on. That is the entire page skeleton — six lines of grid declarations replace what used to be floats, clearfixes, negative margins, and a sticky-footer hack. The min-height: 100vh plus the 1fr middle row makes the footer stick to the bottom on short pages, and 1fr column behavior gives content everything between the 200- and 220-pixel sidebars — on a 1440-pixel viewport, that is 1020 pixels of content. Swapping nav and aside is a one-word edit: change the middle string to 'aside content nav'. Reordering for a right-to-left language needs no HTML changes at all. If hand-writing these maps feels error-prone, our CSS grid generator lets you paint areas visually and exports the quoted strings for you. Template areas also shine when a layout has named landmarks the team talks about — 'hero', 'testimonials', 'pricing' — because the CSS vocabulary matches the design vocabulary, and code review becomes a conversation about regions instead of line numbers.

Responsive re-layout with media queries

Template areas make responsive redesigns almost comically simple, because you only redefine the map — the elements keep their grid-area names. Desktop: 'header header header' 'nav content aside' 'footer footer footer'; Tablet: 'header header' 'nav content' 'aside aside' 'footer footer'; with grid-template-columns: 180px 1fr; — the aside drops to a full-width row beneath content. Phone: 'header' 'content' 'nav' 'aside' 'footer'; with grid-template-columns: 1fr; — everything stacks in an order you choose, which may differ from the DOM order. That last point is the superpower: on mobile you can show content before nav without touching HTML, something Flexbox's order property does per-item but never this declaratively. One breakpoint per device class is usually enough — three maps covering 1200px+, 768–1199px, and under 768px handle 95 percent of sites. The trap: forgetting to change grid-template-columns when the map changes shape — a three-column map with a one-column track definition silently misaligns. Keep each media query self-contained: map, columns, and rows together. Also remember that source order still matters for accessibility — screen readers follow the DOM, not your visual map, so put the main content early in the HTML even if the map shows it second. Visual reordering is a layout tool, not a content-architecture tool.

Common template-area mistakes

Mistake one: mismatched column counts. 'header header' beside 'sidebar main aside' is invalid — the whole declaration dies and auto-placement takes over, which looks like 'my areas are being ignored.' Count your quoted cells per row every time. Mistake two: non-rectangular areas, as covered above — the L-shape that silently fails. Mistake three: quoting each row as one string vs. multiple strings: grid-template-areas: 'header header' 'main main'; is correct; wrapping the whole map in one pair of quotes is not. Mistake four: using area names as class names inconsistently — an element with grid-area: sidebar but a class of .side-bar is a typo waiting to happen; keep a naming convention and stick to it. Mistake five: forgetting that un-named grid children still auto-place — drop a stray div into an areas-based grid and it lands in the first empty cell or creates implicit rows, which is why a missing closing tag can seemingly 'break the whole layout.' Finally, do not use areas for one-dimensional rows — a toolbar of five buttons does not need a map. For more front-end reading on related workflow topics, our open-graph meta tags guide and meta description guide cover the markup layer that pairs with any finished layout. For the content layer, run drafts through the word counter and check search-term usage with our keyword density checker before publishing.

Do it in one click

Paint grid areas visually and export the CSS — free, no signup.

Open the Free Tool →