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; }
RuleDetail
Each string is one rowStrings separated by whitespace, each defines one row
Each word is one columnWords map left-to-right to columns in that row
Span by repeating the name"header header header" spans 3 columns
Empty cellUse . (a dot) for a cell not covered by any named area
Names must be valid identsLetters, digits, -, _; no spaces in a single name
Rectangular shape requiredA 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 */
}
ShorthandEquivalent
grid-template: "a b" 100px / 1fr 2frRows + cols + areas
grid: "a b" auto / 1fr 2frgrid also sets implicit tracks
grid-area: headerName an item for placement
grid-area: 2 / 1 / 4 / 3Explicit 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

PropertyValuesEffect
gap<row-gap> <col-gap>Space between tracks; shorthand for row-gap + column-gap
justify-itemsstart | end | center | stretchAlign items along the row axis within their cells
align-itemsstart | end | center | stretchAlign items along the column axis
place-items<align-items> / <justify-items>Shorthand
justify-contentstart | end | center | space-between | space-around | space-evenlyDistribute columns when tracks don’t fill container
align-contentsame valuesDistribute rows when tracks don’t fill container
place-contentshorthandAlign and justify the whole grid
justify-selfsame as justify-itemsPer-item override for row axis
align-selfsame as align-itemsPer-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 nameTemplate 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-area on an item overrides all four placement lines at once. Setting it after individual grid-row or grid-column declarations discards those declarations.
  • gap does not collapse. Adding gap: 1rem between a header and content that already have margin-bottom stacks both gaps.
  • Items placed outside named areas (via line numbers or auto placement) can overlap named-area items without a z-index.
  • grid-template-areas with a dot . cell does not prevent auto-placed items from filling that cell. Use grid-column: span 1 and explicit placement to prevent it.
  • The fr unit distributes free space after fixed tracks and gaps are subtracted. 1fr in a container with gap: 24px is smaller than 1fr in the same container without a gap.