What are named grid areas (grid-template-areas), and how do they improve layout readability?

Intermediate12 min interview
Skills tested:
Writing a valid grid-template-areas block with matching row string lengthsAssigning items to areas with grid-areaUsing periods for intentionally empty cellsRearranging a layout at a breakpoint by rewriting the templateKnowing that named areas must be rectangular

Advertisement

🧩 Scenario

Named areas are the reason a Grid page shell is readable six months later. A layout expressed as grid-column: 2 / 4 and grid-row: 1 / 2 on five different children requires mentally reconstructing the diagram every time you read it; the same layout expressed as an ASCII block at the container shows the whole structure at a glance and moves regions with a single property rewrite at each breakpoint.

Architecture Walkthrough

Drawing the Layout as Text

grid-template-areas assigns names to grid cells using quoted strings, one string per row, with the names separated by whitespace. Each name occupies a cell, and repeating a name across adjacent cells makes that area span them.

grid-template-areas:
  'header  header'
  'sidebar main'
  'footer  footer';

Three strings means three rows. Two names per string means two columns. header spans both columns of row one, sidebar and main occupy row two, and footer spans row three. Children are then placed with grid-area: header and so on, with no line numbers anywhere.

The readability gain is that the structure lives in one place, at the container, in a form that visually resembles the result. The alternative, line-based placement, distributes the same information across every child as grid-column: 1 / 3 and grid-row: 2 / 3 pairs that have to be mentally reassembled into a diagram.

The Rules That Invalidate a Template

Two constraints are strict, and violating either causes the browser to ignore the entire grid-template-areas declaration rather than partially apply it. That all-or-nothing failure is why the layout collapses to a default grid with no obvious error.

Every row must define the same number of cells. Three names in one string and four in another is invalid. Whitespace is flexible, so aligning the columns visually with extra spaces is encouraged and has no effect on parsing.

Every named area must be a rectangle. An L-shaped or staircase arrangement is invalid. This is the constraint that catches people trying to express a layout Grid cannot represent with a single named area; the solution is either two areas or line-based placement with overlap.

A period marks an intentionally empty cell. A run of periods such as .... counts as one empty cell, which is useful for aligning the ASCII visually while keeping one cell per token position.

Areas Define Lines Automatically

Naming an area implicitly creates named grid lines around it: an area called main gives you main-start and main-end lines on both axes. Those can be referenced directly in grid-column and grid-row, which is how an element can be positioned relative to a named area without being assigned to it. This is the mechanism behind full-bleed patterns where a decorative element spans from full-start to full-end while content sits inside content-start to content-end.

Note also that grid-area is a shorthand with two distinct forms. With a single identifier it assigns a named area. With slash-separated values it takes four line positions in the order row-start / column-start / row-end / column-end. Mixing them up produces confusing results, and the four-value order in particular is not the one most people guess.

Rearranging at a Breakpoint

The strongest practical argument for named areas is responsive rearrangement. Changing a four-region layout from a two-column desktop arrangement to a single-column mobile stack is one property rewrite plus a track change:

@media (max-width: 768px) {
  .shell {
    grid-template-columns: 1fr;
    grid-template-areas:
      'header'
      'main'
      'sidebar'
      'footer';
  }
}

No child selectors change, no order values are set, and the markup is untouched. Compare that to line-based placement, where every child's grid-column and grid-row needs revisiting at each breakpoint, or to Flexbox order, which requires reasoning about each item individually.

The Accessibility Caveat

Because Grid separates visual position from DOM order, rearranging areas can put the visual reading order out of step with the DOM order. Keyboard focus order and screen reader reading order follow the DOM, not the grid. A sidebar moved visually below the main content but still appearing before it in the DOM will be read and tabbed through first.

This is not a reason to avoid named areas; it is a reason to keep the DOM order in a sensible reading sequence and use Grid to adjust presentation within that constraint. When the two genuinely conflict, the DOM order should reflect the logical content order and the visual arrangement should be the thing that bends.


Key Code Explained

/* The canonical page shell */
.shell {
  display: grid;
  grid-template-columns: 240px 1fr;
  grid-template-rows: auto 1fr auto;
  grid-template-areas:
    'header  header'
    'sidebar main'
    'footer  footer';
  min-height: 100dvh;
  gap: 16px;
}
.shell > header { grid-area: header; }
.shell > aside  { grid-area: sidebar; }
.shell > main   { grid-area: main; }
.shell > footer { grid-area: footer; }

/* Rearranging the entire layout: ONE property rewrite */
@media (max-width: 768px) {
  .shell {
    grid-template-columns: 1fr;
    grid-template-areas:
      'header'
      'main'
      'sidebar'
      'footer';
  }
}

/* Periods mark intentionally empty cells.
   A run of dots counts as ONE empty cell. */
.dashboard {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-areas:
    'stats stats chart'
    'table table ....';
}

/* INVALID: row strings define different numbers of cells.
   The whole declaration is ignored — no partial application. */
.broken-count {
  grid-template-areas:
    'a b c'
    'd e';
}

/* INVALID: 'side' is L-shaped, not a rectangle */
.broken-shape {
  grid-template-areas:
    'side main'
    'side side';
}

/* Named areas create named LINES automatically:
   main-start / main-end on both axes */
.overlay {
  grid-column: main-start / main-end;
  grid-row: main-start / main-end;
}

/* The full-bleed pattern using named lines from the track list */
.article {
  display: grid;
  grid-template-columns:
    [full-start] 1fr
    [content-start] minmax(0, 68ch) [content-end]
    1fr [full-end];
}
.article > * {
  grid-column: content;
}
.article > .hero {
  grid-column: full; /* escapes the content column */
}

/* grid-area has TWO forms — do not confuse them */
.by-name {
  grid-area: main; /* named area */
}
.by-lines {
  grid-area: 2 / 1 / 3 / 3; /* row-start / col-start / row-end / col-end */
}

The .shell block plus its media query is the pattern to be able to write from memory, because it demonstrates the entire value proposition in a dozen lines. The desktop and mobile layouts are both readable as diagrams, the transition between them is one declaration, and no child rule is touched. That is the concrete answer to "how do named areas improve readability."

The two INVALID blocks are worth internalising because of how they fail. There is no console warning and no partial layout; the declaration is dropped and the grid falls back to auto-placement, which usually looks like the layout was never written. Knowing that a mismatched row length or a non-rectangular area causes total invalidation makes that failure mode diagnosable in seconds.


Tradeoffs

ApproachWhere the structure livesResponsive rearrangementReadability
grid-template-areasOne block on the containerRewrite one propertyHighest; reads as a diagram
Line numbers on childrenSpread across every childRevisit every child ruleLow; must reconstruct mentally
Named lines on childrenTrack list plus child rulesModerateGood for spans and full-bleed
Flexbox orderOn individual childrenPer-item reasoningLow; and DOM order diverges

What Interviewers Actually Check

  • Whether you can write a valid template with consistent row lengths
  • Whether you know a mismatched row or a non-rectangular area invalidates the whole declaration
  • Whether you know periods mark empty cells
  • Whether you can demonstrate the breakpoint rearrangement advantage
  • Whether you raise the DOM-order accessibility caveat unprompted

Follow-Up Questions

  1. What named lines does an area called main create, and how would you use them without assigning an element to the area?
  2. What are the four values in the slash form of grid-area, and in what order?
  3. How does grid-auto-flow: dense interact with a template that leaves cells empty via periods?
  4. What does display: contents do to a child's participation in the grid, and when is it useful with named areas?
  5. How would subgrid let a nested component align to the parent grid's named areas?

Common Candidate Mistakes

  • Writing row strings with different numbers of cell names, which invalidates the entire grid-template-areas declaration with no warning and leaves the layout looking unstyled
  • Defining an L-shaped or staircase area, which is invalid because every named area must be a solid rectangle
  • Letting the names per row disagree with the number of tracks in grid-template-columns, so the implicit grid absorbs the difference unexpectedly
  • Rearranging areas at a breakpoint without checking that keyboard focus order and screen reader order, which follow the DOM rather than the grid, still make sense
  • Confusing the two forms of grid-area, particularly the four-value slash form whose order is row-start, column-start, row-end, column-end

Interview Readiness Checklist

Before you leave this question, make sure you can answer:

  • Can you write a four-region page shell using grid-template-areas from memory?
  • Can you explain what invalidates a template and what the browser does in that case?
  • Can you use periods to leave deliberate empty cells?
  • Can you rewrite a template in a media query to rearrange a layout without touching child rules?
  • Can you explain the accessibility caveat that comes with visual reordering?

Summary

grid-template-areas names grid cells with quoted strings, one per row, and repeating a name across adjacent cells makes an area span them. Children are assigned with grid-area: <name>, so the entire layout structure lives in a single readable block on the container rather than being distributed across every child as line numbers that must be mentally reassembled.

Two rules are strict. Every row string must define the same number of cells, and every named area must form a solid rectangle. Violating either invalidates the whole declaration, with no warning and no partial application, which is why the symptom is a layout that looks like it was never written. Periods mark intentionally empty cells, and a run of periods counts as a single empty cell, which lets you align the ASCII visually.

The strongest practical benefit is responsive rearrangement: moving from a two-column desktop shell to a single-column mobile stack is one template rewrite plus a track change, with no child rules touched and no order values to reason about. Naming an area also creates <name>-start and <name>-end lines on both axes, which is what makes full-bleed and overlay patterns straightforward. The one caveat to raise is that keyboard focus and screen reader order follow the DOM rather than the grid, so the DOM should carry the logical reading order and the visual arrangement should be what adapts.

Frequently Asked Questions

What does a period mean inside grid-template-areas?

A single period or a run of periods marks an empty cell that no named area occupies. Runs of periods are treated as one empty cell each, so use them to leave deliberate gaps in the structure.

Can a named area be non-rectangular?

No. Every named area must form a solid rectangle. A non-rectangular arrangement makes the whole grid-template-areas declaration invalid and it is ignored entirely.

Advertisement


Stay Updated

Get the latest frontend challenges, interview questions and tutorials delivered to your inbox.

Advertisement