Grid Placement & Areas
In CSS Grid Basics the browser placed every item for you, one after another. That automatic placement is fine for a gallery, but a page layout or a dashboard needs more control: this box across two columns, that one in the bottom-right corner, the footer along the full width.
This lesson shows two ways to place items exactly: by grid line numbers and by named areas. You will also see how to overlap items and why the HTML order still matters.
Grid lines are numbered
Every grid has numbered lines between and around its tracks. A grid with three columns has four vertical lines: line 1 on the left edge, then lines 2 and 3 between the columns, and line 4 on the right edge. Rows work the same way from top to bottom.
Lines are also numbered backwards from the end with negative numbers. Line -1 is always the last line of the explicit grid, so 1 / -1 means "from the first line to the last", whatever the number of columns.
Browser DevTools can draw these numbers for you. In Chrome, Edge or Firefox, open DevTools, select a grid container and click the small "grid" badge next to it in the Elements panel.
Placing items with line numbers
grid-column and grid-row take a start line and an end line separated by a slash. Instead of an end line, you can write span and a number of tracks.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Dashboard placement</title>
<style>
body { font-family: system-ui, sans-serif; margin: 16px; }
.dashboard {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-auto-rows: 90px;
gap: 10px;
}
.dashboard div {
padding: 10px;
border-radius: 8px;
background: #e0e7ff;
}
.sales { grid-column: 1 / 3; grid-row: 1 / 3; background: #c7d2fe; }
.orders { grid-column: 3 / -1; }
.visitors { grid-column: span 2; }
.notes { grid-column: 1 / -1; }
</style>
</head>
<body>
<div class="dashboard">
<div class="sales">Sales this week: ₹48,200</div>
<div class="orders">Orders: 126</div>
<div class="visitors">Visitors: 2,310</div>
<div class="notes">Note: Diwali offer ends on Friday</div>
</div>
</body>
</html>Here is how each box is placed:
- Sales runs from column line 1 to line 3 and from row line 1 to line 3, so it covers a 2 by 2 block.
- Orders runs from line 3 to the last line, filling the top-right.
- Visitors only says
span 2. The browser finds the first free space that is two columns wide, which is next to Sales in row 2. - Notes runs from the first to the last line, so it takes the full width of row 3.
The grid-area property can set all four lines at once in the order row-start, column-start, row-end, column-end. grid-area: 1 / 1 / 3 / 3 would place Sales exactly as above. It is short but harder to read, so many developers prefer grid-column and grid-row.
Naming lines
Numbers are hard to remember in a big layout. You can give lines names by writing them in square brackets inside the track list. A popular use is an article layout where text stays in a readable centre column but some items stretch to the edges.
.article {
display: grid;
grid-template-columns:
[full-start] 1fr
[content-start] min(65ch, 100% - 2rem) [content-end]
1fr [full-end];
}
.article > * {
grid-column: content; /* normal text stays in the middle */
}
.article > .wide-photo {
grid-column: full; /* photos run edge to edge */
}When lines are named something-start and something-end, Grid lets you use just something as a shortcut for the whole span between them. That is why grid-column: content works here. The centre column is never wider than 65 characters, which is comfortable to read, and on a phone it shrinks to the screen width minus 2rem.
Drawing a layout with grid-template-areas
grid-template-areas lets you draw the layout as a picture made of words. Each string in quotes is one row, and each word is one cell. Repeat a word to make an area cover several cells. Then give each item a matching grid-area name.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Page areas</title>
<style>
body { margin: 0; font-family: system-ui, sans-serif; }
.page {
display: grid;
gap: 10px;
padding: 10px;
grid-template-areas:
"header"
"main"
"sidebar"
"footer";
}
.page > * { padding: 16px; border-radius: 8px; background: #f1f5f9; }
header { grid-area: header; background: #1e3a8a; color: white; }
main { grid-area: main; min-height: 200px; }
aside { grid-area: sidebar; background: #fef9c3; }
footer { grid-area: footer; background: #e2e8f0; }
@media (min-width: 40rem) {
.page {
grid-template-columns: 1fr 220px;
grid-template-areas:
"header header"
"main sidebar"
"footer footer";
}
}
</style>
</head>
<body>
<div class="page">
<header>Lucknow Cricket Academy</header>
<main>Match reports and coaching news go here.</main>
<aside>Upcoming fixtures</aside>
<footer>Contact the academy office</footer>
</div>
</body>
</html>On a narrow screen everything stacks in one column. From 40rem wide, the media query draws a new picture: the header and footer span both columns and the sidebar sits next to the main content. Only the grid container changes; the items keep their area names. You will learn more about media queries in Responsive Design & Media Queries.
A few rules for the picture:
- Every string must have the same number of words (cells).
- Each area must be a rectangle. An L-shaped area is invalid, and the whole declaration is ignored.
- Use a full stop
.for an empty cell, for example"header .".
Overlapping items
Two items can be placed in the same cell. This is a clean way to put text on top of an image without position: absolute.
.hero {
display: grid;
grid-template-areas: "stack";
}
.hero > * {
grid-area: stack; /* image and caption share one cell */
}
.hero .caption {
align-self: end; /* caption sits at the bottom of the image */
z-index: 1;
padding: 1rem;
background: rgb(0 0 0 / 0.6);
color: white;
}When items overlap, later items in the HTML are drawn on top. Grid items also accept z-index without needing position, so you can control the stacking order directly.
Common mistakes
- Counting columns instead of lines. A three-column grid ends at line 4, not line 3. Use
-1when you mean "the last line". - Uneven area strings. If one row has three words and another has two, the browser ignores the whole
grid-template-areasdeclaration and the items land in unexpected places. - Area names that do not match.
grid-area: sidewill not land in an area calledsidebar. Check the spelling in both places. - Writing quotes around
grid-areavalues. Usegrid-area: header, notgrid-area: "header". Quotes belong only ingrid-template-areas.
Key points
- Grid lines are numbered from 1, and negative numbers count from the end, so
1 / -1spans the full explicit grid. grid-columnandgrid-rowtake a start and an end line, or aspancount.- Named lines such as
[content-start]and[content-end]let you writegrid-column: content. grid-template-areasdraws the layout as rows of words; items join an area withgrid-area.- Change the template inside a media query to rearrange the whole layout without touching the items.
- Items can overlap in the same cell; the HTML order should still be the reading order.
Exercise
Create a layout for a school notice board with four parts: a title bar, a "Notices" area, an "Events" area and a "Contact" strip. On small screens, stack them in that order. From 48rem wide, use two columns: the title bar and contact strip across the full width, with Notices and Events side by side. Use grid-template-areas.
Show solution
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Notice board</title>
<style>
.board {
display: grid;
gap: 12px;
grid-template-areas: "title" "notices" "events" "contact";
}
.title { grid-area: title; }
.notices { grid-area: notices; }
.events { grid-area: events; }
.contact { grid-area: contact; }
@media (min-width: 48rem) {
.board {
grid-template-columns: 1fr 1fr;
grid-template-areas:
"title title"
"notices events"
"contact contact";
}
}
</style>
</head>
<body>
<div class="board">
<h1 class="title">Kochi Public School</h1>
<section class="notices">Notices</section>
<section class="events">Events</section>
<p class="contact">Office: 9 am to 4 pm</p>
</div>
</body>
</html>The items only declare which area they belong to. The media query swaps in a two-column picture, and the title and contact strip repeat their names to span both columns.
Quick Quiz
1. In a grid with four columns, what does grid-column: 1 / -1 do?
Line -1 is the last line of the explicit grid, so the item runs from the first line to the last.
2. What does grid-column: span 3 mean?
span sets how many tracks the item covers, while the browser still chooses the start position.
3. Which grid-template-areas value is invalid?
Area a would be L-shaped in the third option. Every named area must form a rectangle.
4. Why should you avoid using Grid to show content in a very different order from the HTML?
Visual placement does not change the document order that assistive technology and the Tab key use.
Learn CSS with a mentor
Free lessons get you started. Our Full Stack Web Development training adds real projects and code reviews from working developers.
- Project-based learning
- Mentor code reviews
- Free counselling call
