Command Palette

Search for a command to run...

Hectal
PHASE 8Intermediate ~26 min· topic 4 of 6

Topic 8.4

Template Areas

In one line

grid-template-areas lets you draw a layout as text, one quoted string per row and one name per cell; each item then joins its area with grid-area: name, and changing the drawing in a media query rearranges the whole page.

Think of it like this

Planning a garden on squared paper. You write a letter in each square: T for tomatoes, F for flowers, a dot for an empty square. All the T squares together make the tomato bed. You can see the whole garden at a glance, and to move the flowers you rewrite a few letters instead of measuring anything. grid-template-areas is that squared paper.

Words you'll meet

New words in this topic, in plain English. Come back here whenever one feels fuzzy.

`grid-template-areas`
A property where you draw the layout as quoted strings, one per row, with a name in each cell.
Area name
A word you invent, like header, written in the cells an area should cover.
`grid-area: name`
Put on an item to place it into the area with that name.
Empty cell
A cell marked with a dot ., where no named area goes.
Rectangle rule
Every named area must form one solid rectangle, or the whole drawing is ignored.
`grid-template`
A shorthand that sets areas, row sizes and column sizes in one declaration.
Implicit named lines
The lines name-start and name-end that every named area creates automatically.

Step by step

01Sketch the layout

On paper, a classic page: a header across the top, a sidebar and main content side by side, a footer across the bottom. That's 3 rows and 2 columns.

Sketch the layoutdiagram
Rendering diagram…

02Write the sketch as strings

One string per row, one name per column. The strings line up like the picture.

style.csswhole filecss
.page {
  display: grid;
  grid-template-areas:
    "header  header"
    "sidebar main"
    "footer  footer";
}

03Give the tracks sizes

The areas only name the cells. Add a 200px sidebar column and a flexible main column, and let the middle row take the remaining height.

style.csswhole filecss
.page {
  display: grid;
  grid-template-areas:
    "header  header"
    "sidebar main"
    "footer  footer";
  grid-template-columns: 200px 1fr;
  grid-template-rows: auto 1fr auto;
  min-height: 100vh;
  gap: 16px;
}

04Put each item in its area

Each child says which area it belongs to. The order of the children in the HTML no longer decides where they go.

style.csswhole filecss
.page > header { grid-area: header; }
.page > nav    { grid-area: sidebar; }
.page > main   { grid-area: main; }
.page > footer { grid-area: footer; }

05Leave a cell empty

Want the footer only under the main content? Put a dot in the sidebar column of the last row. The dot is one empty cell.

style.csswhole filecss
grid-template-areas:
  "header  header"
  "sidebar main"
  ".       footer";

06Redraw it for phones

Write the one-column drawing first (mobile first), then redraw it for wide screens. Only the strings and track sizes change.

style.csswhole filecss
.page {
  display: grid;
  grid-template-areas: "header" "main" "sidebar" "footer";
}
@media (min-width: 700px) {
  .page {
    grid-template-columns: 200px 1fr;
    grid-template-areas:
      "header  header"
      "sidebar main"
      "footer  footer";
  }
}

Try it yourself

  1. 1

    Move the sidebar to the right

    In the first example, change only the strings so the sidebar is on the right, and swap the column sizes to 1fr 100px. Predict the new x values for nav and main (main at 0, nav at 300), then run.

  2. 2

    Add an empty cell

    In the first example, change the last row to ". footer". Predict the footer's x and width (108 and 292). Run and check.

  3. 3

    Fix the typo

    In the second example, add a second row to .ok so area c exists: grid-template-areas: "a b" "c c";. Predict where the red item goes now (x=0 y=40, across both columns).

Code & diagrams

A page layout drawn with areas New tab

The computed value prints the drawing back as strings. Each item filled the rectangle its name covers: the header and footer are the full 400px wide.

Preview

Press Run to see the page.

Console

Nothing logged yet.

Expected console output

"header header" "sidebar main" "footer footer"
header x=0 y=0 400x40
nav x=0 y=48 100x100
main x=108 y=48 292x100
footer x=0 y=156 400x30
Invalid drawings and a misspelt name New tab

Both broken drawings compute to `none`: the whole declaration is dropped. The item asking for a missing area `c` isn't hidden; it lands in implicit tracks beyond the end of the explicit grid, below and to the right of everything else.

Preview

Press Run to see the page.

Console

Nothing logged yet.

Expected console output

.ok "a b"
.l-shape none
.uneven none
typo item at x=250 y=70
Rearrange with a media query New tab

Make the preview narrower and wider (or open it full screen): under 500px everything stacks; above it the aside moves beside the main content. The HTML never changes, and it stays in reading order.

Preview

Press Run to see the page.

Console

Nothing logged yet.
Areas create lines, lines create areasdiagram
Rendering diagram…

Break it on purpose

Errors are the best teachers. Make each change, read the error, guess what went wrong, then reveal the answer.

Break #1

Draw an L-shaped area

Write grid-template-areas: "nav main" "nav nav"; to make the nav wrap under the main content.

terminal
$ the page shows
── what you'll see ──
The layout collapses: every item stacks in one column. DevTools strikes the declaration through as an invalid value.

Break #2

Quote the name on the item

Write grid-area: "header"; on the header element.

terminal
$ the page shows
── what you'll see ──
The header is not in the header area; it's auto-placed into the next free cell.

Myth vs fact

Myth

Area names must match class names or element names.

Fact

They're independent identifiers you invent. Matching them is only a readability habit.

Myth

... is three empty cells.

Fact

A run of dots with no spaces between them is one empty cell. Write . . . (with spaces) for three.

Myth

Rearranging areas is a safe way to change the order of content.

Fact

It changes only the visual order. Screen readers and Tab follow the HTML, so a big difference between the two confuses people. Keep the HTML in a logical order.

Pro corner

Extra depth for experienced readers. New to this? Skip it for now and come back later.

  • ▸

    Rows in grid-template-areas with different cell counts, non-rectangular areas, or an area split in two make the value invalid at parse time, which is why it computes to none rather than a partly working layout.

  • ▸

    If the area strings have more columns than grid-template-columns, the extra columns become implicit tracks sized by grid-auto-columns. The explicit grid is the larger of the two in each direction.

  • ▸

    A missing area name on an item resolves its lines as implicit named lines after the explicit grid, so the item ends up in implicit tracks beyond the explicit grid instead of disappearing. In DevTools, the grid overlay's Show area names option makes such typos obvious.

  • ▸

    grid-template and grid are shorthands that reset the properties they don't mention (grid also resets grid-auto-*). Writing grid-template-areas after them is fine, but writing grid-template: … after grid-template-areas wipes the areas.

Remember this

  1. 1

    grid-template-areas takes one quoted string per row. Inside each string, write one name per column, separated by spaces. Repeating a name across neighbouring cells makes that area bigger: "header header" "sidebar main" "footer footer" is three rows and two columns, with the header and footer stretched across both columns. Put each string on its own line so the code looks like the layout.

  2. 2

    Each item joins an area with **grid-area: name** (no quotes): .site-header { grid-area: header; }. The item fills the whole rectangle covered by that name. The names are yours to choose, like custom class names; they must not start with a digit, and they don't need to match class names, though matching them keeps things readable.

  3. 3

    A dot . marks an empty cell that no area uses. Several dots written together without spaces (...) still count as one cell, which helps line up the columns of your drawing. Areas must be rectangles: an L shape, a name used in two separate places, or rows with different numbers of cells make the whole declaration invalid, so it is dropped and nothing is placed by name.

  4. 4

    grid-template-areas only names cells; the sizes still come from grid-template-columns and grid-template-rows. The number of columns in your strings should match the column template; if they differ, the browser adds implicit tracks to make them agree. The **grid-template** shorthand writes all three together, with each row size after its string and the columns after a slash: grid-template: "head head" 60px "side main" 1fr / 200px 1fr;.

  5. 5

    Every named area also creates named lines for free: an area called main gives you lines main-start and main-end in both directions. So an item can say grid-column: main-start / main-end, or another item can overlap the area with grid-area: main. The reverse works too: lines you named content-start and content-end create an implicit area called content.

  6. 6

    Areas make responsive layouts short and clear. On phones, draw one column: "header" "main" "sidebar" "footer". Inside a media query (Phase 9) for wider screens, redraw it with the sidebar beside the main content. The HTML and the items' grid-area names never change. Remember that moving areas changes only the visual order: keyboard focus and screen readers still follow the HTML, so keep the source order sensible.

Explain it without notes

01

How does grid-template-areas work, and how does an item join an area?

02

What makes a grid-template-areas value invalid, and what happens then?

03

How would you make a layout that is one column on phones and has a sidebar on desktops, using areas?

04

What named lines does an area create, and how can you use them?

Practice

01

Draw a dashboard: a header across the top; below it a narrow menu on the left and two equal panels side by side on the right; no footer.

02

Write a grid-template shorthand for a 2-column layout with rows header (60px), side main (1fr) and foot foot (40px), and columns 180px 1fr.

03

A card has an image, a title and text. Use areas so the image is on the left spanning both rows, the title top-right and the text bottom-right.

Trade-offs

  • ↔

    Areas read like a picture and make responsive rearranging trivial, but every cell must be named or dotted, so very big or irregular grids are clearer with line numbers or spans.

  • ↔

    Large visual reordering with areas is easy to write and easy to get wrong for accessibility; keep visual order and source order close.

Done when you can

  • I can draw a layout with grid-template-areas and place items with grid-area: name.

  • I can leave cells empty with . and keep areas rectangular.

  • I can use the grid-template shorthand.

  • I can rearrange a layout for different screen widths by redrawing the areas.

  • I can use the -start/-end lines an area creates.