Home / Articles / Layout /

layoutgrid

grid-template-areas: named layout regions

Named grid areas let you sketch your layout in CSS as if you were drawing it on graph paper. The result is the most readable way to define page structure.

The basic syntax

grid-template-areas accepts a series of quoted strings. Each string represents one row. Each word in a string names a cell. Repeating a name spans that area across multiple columns or rows.

.page {
  display: grid;
  grid-template-areas:
    "header  header"
    "sidebar main"
    "footer  footer";
  grid-template-columns: 16rem 1fr;
  grid-template-rows: auto 1fr auto;
  min-height: 100dvh;
}

.page__header  { grid-area: header; }
.page__sidebar { grid-area: sidebar; }
.page__main    { grid-area: main; }
.page__footer  { grid-area: footer; }

Each child uses grid-area to claim its named region. The order of children in the HTML no longer matters for visual placement.

Empty cells with the dot token

Use a dot (.) to leave a cell empty. Multiple dots can be used for readability — ... counts as a single empty cell, same as ..

.dashboard {
  display: grid;
  grid-template-areas:
    "nav    nav    nav"
    "stats  ...    chart"
    "table  table  table";
  grid-template-columns: 1fr 2rem 1fr;
  grid-template-rows: auto 1fr auto;
  gap: 1.5rem;
}

/* The middle cell in row 2 is empty — acts as a visual gutter.
   This is an alternative to using gap when you need
   different spacing in different areas. */

Responsive layouts with area rearrangement

The real power of named areas shows up in responsive design. You can completely rearrange the layout in a media query by redefining only grid-template-areas and the track definitions. No changes to the HTML, no repositioning individual items.

/* Mobile: single column stack */
.page {
  display: grid;
  grid-template-areas:
    "header"
    "main"
    "sidebar"
    "footer";
  grid-template-columns: 1fr;
}

/* Desktop: sidebar layout */
@media (min-width: 60rem) {
  .page {
    grid-template-areas:
      "header  header"
      "sidebar main"
      "footer  footer";
    grid-template-columns: 16rem 1fr;
    grid-template-rows: auto 1fr auto;
  }
}
Named areas decouple visual order from source order. This is great for layout but be careful: screen readers follow DOM order, so ensure the source order is still logical.

Implicit named lines

When you define a named area, the browser automatically creates named lines around it. An area called main creates lines called main-start and main-end on both axes. You can reference these lines directly for precise placement.

.page {
  grid-template-areas:
    "header header"
    "nav    main"
    "footer footer";
  grid-template-columns: 14rem 1fr;
}

/* Place an overlay spanning from main-start to the end */
.overlay {
  grid-column: main-start / -1;
  grid-row: main-start / footer-start;
  background: oklch(0.1 0.02 260 / 0.8);
}

Combining areas with track sizing

Named areas work alongside all Grid track-sizing features: minmax(), fr units, auto, and fixed lengths. Define the areas for placement and the track templates for sizing.

.app {
  display: grid;
  grid-template-areas:
    "toolbar toolbar  toolbar"
    "nav     content  aside"
    "nav     content  aside";
  grid-template-columns: minmax(12rem, 16rem) 1fr minmax(14rem, 20rem);
  grid-template-rows: auto 1fr;
  gap: 1rem;
  height: 100dvh;
}

.app__toolbar { grid-area: toolbar; }
.app__nav     { grid-area: nav; }
.app__content { grid-area: content; overflow-y: auto; }
.app__aside   { grid-area: aside; }

Rules and common mistakes

Named areas must form rectangles. L-shapes, T-shapes, and other non-rectangular regions are invalid and the entire declaration will be ignored.

/* VALID — "hero" spans two columns, forming a rectangle */
grid-template-areas:
  "hero   hero"
  "left   right";

/* INVALID — "hero" forms an L-shape */
grid-template-areas:
  "hero   sidebar"
  "hero   hero";
/* The browser ignores this entire declaration */

/* VALID — every row must have the same number of cells */
grid-template-areas:
  "a b c"
  "d e f";

/* INVALID — different column counts per row */
grid-template-areas:
  "a b"
  "c d e";
  • All rows must have the same number of columns.
  • Named areas must form rectangles — no L-shapes or diagonals.
  • Area names are case-sensitive: Header and header are different areas.
  • Use grid-area on children, not grid-row/grid-column, to place items in named areas.