Skip to content
Laviyx Learn

Try

CSS course menu

CSS Grid Lines and grid-template-areas: Placing Items and Page Layouts

Place CSS grid items precisely with grid lines (grid-column, grid-row, negative line numbers), name regions with grid-template-areas to build page layouts, change layouts with media queries, and line up nested content with subgrid.

Intermediate8 min readUpdated
On this page

In the CSS Grid lesson, items flowed into cells automatically. You can also put items in exact positions, either by line numbers or by naming areas of the grid.

Grid lines#

Grid lines are the lines between tracks, numbered from 1. A 3-column grid has 4 vertical lines:

Text
line: 1        2        3        4
      |  col 1 |  col 2 |  col 3 |

grid-column: start / end places an item between two lines:

CSS
.grid { display: grid; grid-template-columns: repeat(3, 1fr); grid-auto-rows: 50px; gap: 6px; }
.grid div { background: #2f5fe0; color: white; padding: 6px; font: 13px monospace; }
.a { grid-column: 1 / 3; }          /* lines 1 to 3: two columns */
.b { grid-column: 3; grid-row: 1 / 3; }
.c { grid-column: 1 / -1; }         /* -1 is the last line: full width */
HTML
<div class="grid">
  <div class="a">grid-column: 1 / 3</div>
  <div class="b">col 3, rows 1 / 3</div>
  <div>auto</div>
  <div>auto</div>
  <div class="c">grid-column: 1 / -1</div>
</div>
Result
  • Negative numbers count from the end: -1 is the last line, so 1 / -1 always spans the full width.
  • span n (from the previous lesson) can be combined with a line: grid-column: 2 / span 2.

grid-template-areas#

For page layouts, naming areas is often clearer. Draw the layout as text, with one string per row:

CSS
.page {
  display: grid;
  grid-template-columns: 160px 1fr;
  grid-template-rows: auto 1fr auto;
  grid-template-areas:
    "header  header"
    "sidebar main"
    "footer  footer";
  gap: 8px;
  min-height: 260px;
  font-family: system-ui, sans-serif;
}
.page > * { padding: 10px; border-radius: 6px; color: white; }
header  { grid-area: header;  background: #1d3b4f; }
aside   { grid-area: sidebar; background: #0f8a7e; }
main    { grid-area: main;    background: #2f5fe0; }
footer  { grid-area: footer;  background: #555; }
HTML
<div class="page">
  <header>Header</header>
  <aside>Sidebar</aside>
  <main>Main content</main>
  <footer>Footer</footer>
</div>
Result
  • Each string is a row; each word is a cell. A name repeated across cells makes the area span them.
  • Areas must be rectangles.
  • A . marks an empty cell: "header .".
  • Each item is assigned with grid-area: name.

Changing layout at different sizes#

Because the layout is a picture in one property, a media query can redraw it. Here the sidebar moves below the main content on narrow screens:

CSS
.page {
  grid-template-columns: 1fr;
  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";
  }
}

The HTML order stays the same, so keyboard and screen reader order stays logical. Only rearrange visually when the reading order still makes sense. Media queries are explained in Media Queries.

subgrid#

Normally a grid item's own children do not line up with the outer grid. grid-template-rows: subgrid (or columns) lets a nested grid reuse its parent's tracks, so headings, text and buttons line up across cards:

CSS
.cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
}
.card {
  display: grid;
  grid-row: span 3;
  grid-template-rows: subgrid;
  gap: 4px;
  padding: 10px;
  border: 1px solid #ccc;
  border-radius: 8px;
}
.card h3, .card p { margin: 0; }
HTML
<div class="cards">
  <article class="card"><h3>Short</h3><p>One line.</p><a href="#">Buy</a></article>
  <article class="card"><h3>A much longer heading that wraps</h3><p>Text.</p><a href="#">Buy</a></article>
  <article class="card"><h3>Medium title</h3><p>A longer description that takes a few more lines to finish.</p><a href="#">Buy</a></article>
</div>
Result

The headings, paragraphs and links line up across all three cards, because they share the same three rows. Subgrid is supported in current versions of all major browsers.

Practice#

Practice exercise

Build a dashboard with grid-template-areas: a full-width "top" bar, then three columns where "nav" is on the left, "stats" in the middle and "alerts" on the right, and a "chart" area under stats and alerts spanning both of those columns.

Show solution
CSS
.dash {
  display: grid;
  grid-template-columns: 120px 1fr 1fr;
  grid-template-areas:
    "top top    top"
    "nav stats  alerts"
    "nav chart  chart";
  gap: 6px;
  min-height: 220px;
}
.dash > div { padding: 8px; background: #eef3ff; border: 1px solid #c5d4fb; border-radius: 6px; }
.top { grid-area: top; }
.nav { grid-area: nav; }
.stats { grid-area: stats; }
.alerts { grid-area: alerts; }
.chart { grid-area: chart; }
HTML
<div class="dash">
  <div class="top">Top bar</div>
  <div class="nav">Nav</div>
  <div class="stats">Stats</div>
  <div class="alerts">Alerts</div>
  <div class="chart">Chart</div>
</div>
Result

Key takeaway#

Finished this lesson?