Intermediate10 min read

CSS Grid Advanced: grid-template-areas and Named Lines

10 min read
250 words
15 sections14 code blocks

grid-template-areas Revisited

grid-template-areas lets you define your layout using a visual, text-based map. Each string represents a row, and each word within the string represents a column.

CSS
.layout {
  display: grid;
  grid-template-areas:
    "header  header  header"
    "sidebar content content"
    "footer  footer  footer";
  grid-template-columns: 250px 1fr 1fr;
  grid-template-rows: auto 1fr auto;
  min-height: 100vh;
}

Assigning Elements to Areas

Use grid-area to place elements into named areas:

CSS
.header  { grid-area: header; }
.sidebar { grid-area: sidebar; }
.content { grid-area: content; }
.footer  { grid-area: footer; }

The matching HTML:

HTML
<div class="layout">
  <header class="header">Header</header>
  <aside class="sidebar">Sidebar</aside>
  <main class="content">Content</main>
  <footer class="footer">Footer</footer>
</div>

Empty Cells with Dots

Use a period (.) to create empty cells:

CSS
.layout {
  grid-template-areas:
    "header header header"
    "sidebar content ."
    "footer footer footer";
}

Multiple dots work too (for readability):

CSS
grid-template-areas:
  "header  header  header"
  "sidebar content ......"
  "footer  footer  footer";

Responsive Layouts with grid-template-areas

The real power comes from redefining areas at different breakpoints:

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

/* Tablet: sidebar beside content */
@media (min-width: 768px) {
  .layout {
    grid-template-areas:
      "header  header"
      "sidebar content"
      "footer  footer";
    grid-template-columns: 250px 1fr;
  }
}

/* Desktop: three-column with right sidebar */
@media (min-width: 1200px) {
  .layout {
    grid-template-areas:
      "header  header  header"
      "sidebar content aside"
      "footer  footer  footer";
    grid-template-columns: 250px 1fr 200px;
  }
}

The HTML never changes — only the CSS grid map adapts.

Named Grid Lines

Instead of using line numbers, you can name your grid lines:

CSS
.grid {
  display: grid;
  grid-template-columns:
    [sidebar-start] 250px
    [sidebar-end content-start] 1fr
    [content-end];
  grid-template-rows:
    [header-start] auto
    [header-end main-start] 1fr
    [main-end footer-start] auto
    [footer-end];
}

Placing Items with Named Lines

CSS
.header {
  grid-column: sidebar-start / content-end;
  grid-row: header-start / header-end;
}

.sidebar {
  grid-column: sidebar-start / sidebar-end;
  grid-row: main-start / main-end;
}

.content {
  grid-column: content-start / content-end;
  grid-row: main-start / main-end;
}

Implicit Named Lines from Areas

When you use grid-template-areas, CSS automatically creates named lines:

CSS
.layout {
  grid-template-areas:
    "header header"
    "sidebar content";
}

/* These named lines are auto-created: */
/* header-start, header-end */
/* sidebar-start, sidebar-end */
/* content-start, content-end */

/* So you can do: */
.overlay {
  grid-column: header-start / header-end;
  grid-row: sidebar-start / content-end;
}

Repeat with Named Lines

CSS
.grid {
  grid-template-columns: repeat(3, [col-start] 1fr [col-end]);
}

/* Reference specific repetitions */
.item {
  grid-column: col-start 2 / col-end 3;
  /* Starts at the 2nd col-start, ends at the 3rd col-end */
}

Complex Layout Patterns

Dashboard Layout

CSS
.dashboard {
  display: grid;
  grid-template-areas:
    "nav    nav    nav"
    "stats  stats  stats"
    "chart  chart  table"
    "chart  chart  list";
  grid-template-columns: 1fr 1fr 350px;
  grid-template-rows: auto auto 1fr 1fr;
  gap: 1rem;
  min-height: 100vh;
  padding: 1rem;
}

.dashboard__nav   { grid-area: nav; }
.dashboard__stats { grid-area: stats; }
.dashboard__chart { grid-area: chart; }
.dashboard__table { grid-area: table; }
.dashboard__list  { grid-area: list; }

Magazine Layout

CSS
.magazine {
  display: grid;
  grid-template-areas:
    "featured featured sidebar"
    "article1 article2 sidebar"
    "article3 article3 sidebar";
  grid-template-columns: 1fr 1fr 300px;
  grid-template-rows: 400px auto auto;
  gap: 1.5rem;
}

.featured { grid-area: featured; }
.sidebar  { grid-area: sidebar; }
CSS
.card-grid {
  display: grid;
  grid-template-areas:
    "featured featured normal1"
    "featured featured normal2"
    "normal3  normal4  normal5";
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 200px);
  gap: 1rem;
}

.card--featured { grid-area: featured; }

Overlapping Grid Items

Unlike flexbox, grid items can overlap by placing them in the same cells:

CSS
.grid {
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: 300px;
}

.image {
  grid-column: 1;
  grid-row: 1;
}

.overlay-text {
  grid-column: 1;
  grid-row: 1;
  align-self: end;
  padding: 2rem;
  background: linear-gradient(transparent, rgba(0,0,0,0.7));
  color: white;
  z-index: 1;
}

Debugging Grid Layouts

Most browser DevTools have a Grid Inspector that shows:

  • Grid lines and their numbers
  • Named areas highlighted with colors
  • Gap visualization
  • Item placement

In Chrome: Open DevTools, click the grid badge next to a grid container in the Elements panel.

Summary

grid-template-areas creates visual, intuitive layouts that are easy to read and modify. Named areas automatically create named lines for precise item placement. Combine areas with responsive media queries to completely rearrange layouts without changing HTML. Use named grid lines for complex placement, and take advantage of grid's ability to overlap items for creative designs.