Grid Item Placement
Precisely place grid items using grid-column and grid-row with line numbers and spans, use grid-area as a placement shorthand, and build readable layouts with named grid-template-areas.
Defining tracks is only half of Grid — the other half is telling individual items where to sit within that structure. Grid gives you two complementary approaches: precise line-based placement (grid-column, grid-row) for numeric control, and human-readable named areas (grid-template-areas) that turn your CSS into something that visually resembles the layout it produces.
grid-column and grid-row with line numbers
Every grid item can be positioned using the numbered grid lines from the earlier fundamentals lesson. grid-column: 1 / 3 places an item starting at column line 1 and ending at column line 3 — meaning it spans across columns 1 and 2 (two column tracks), because the end value is exclusive, marking where the item stops rather than a track it occupies. grid-row works identically for the vertical direction.
Instead of specifying both a start and end line, you can use the span keyword to say how many tracks to cover from the start line: grid-column: 1 / span 2 places the item starting at line 1 and spanning 2 column tracks — equivalent to grid-column: 1 / 3. span is often more intuitive because you don't need to calculate the ending line number yourself.
grid-column and grid-row are themselves shorthands: grid-column combines grid-column-start and grid-column-end; grid-row combines grid-row-start and grid-row-end.
• grid-column: <start-line> / <end-line> — end line is exclusive (marks where the item stops) • grid-column: <start-line> / span <count> — spans a number of tracks from the start line • grid-row works identically, but for horizontal row lines • Negative line numbers count backward from the last line (-1 is always the final line)
grid-area as a placement shorthand
grid-area can act as an even shorter shorthand for all four placement longhands at once, in the order: grid-row-start / grid-column-start / grid-row-end / grid-column-end. So grid-area: 1 / 1 / 3 / 3 places an item starting at row line 1, column line 1, ending at row line 3, column line 3 — a 2x2 block in the top-left of the grid.
But grid-area has a second, arguably more useful job: assigning a name to an item so it can be referenced from a named grid-template-areas layout, covered next.
Named grid-template-areas
grid-template-areas lets you literally draw your layout using named strings, where each string represents one row and each word in it represents which named area occupies that cell. Every grid item that should occupy a named region gets a matching grid-area: <name> declaration. Cells that should stay empty use a period (.) instead of a name.
This approach is powerful because the CSS becomes self-documenting — you can look at the grid-template-areas block and visually recognize the page structure (header across the top, sidebar down the left, main content in the middle, footer across the bottom) without mentally tracking line numbers. It's the most readable way to build page-level layouts in Grid, and it's far easier to maintain when a layout changes, since you just redraw the ASCII-like map instead of recalculating line numbers everywhere.
One rule to remember: every row string in grid-template-areas must have the same number of words (columns), and a named area must always form a rectangle — it can't skip around or form an L-shape.
• grid-template-areas: rows expressed as quoted strings of area names • Matching grid-area: <name> on each item assigns it to that named region • A period (.) marks an empty cell • Every named area must form a single rectangle — no L-shapes or gaps within an area
Both placement approaches side by side
Every row string in grid-template-areas must contain the same number of area names A dot (.) in grid-template-areas marks a deliberately empty cell
/* Line-based placement */
.item {
grid-column: 2 / span 2;
grid-row: 1 / 3;
}
/* Named-area placement */
.container {
display: grid;
grid-template-columns: 200px 1fr;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"sidebar header"
"sidebar main"
"sidebar footer";
}
.sidebar { grid-area: sidebar; }
.header { grid-area: header; }
.main { grid-area: main; }
.footer { grid-area: footer; }Code Examples
grid-column: 1 / -1 stretches an item across every column of the grid, regardless of how many columns exist, because -1 always refers to the final grid line — a handy pattern for full-width banners.
grid-column: 1 / -1;
Reading the grid-template-areas block top to bottom is almost like looking at a wireframe of the page: a full-width header, a three-column middle row (nav, main, aside), and a full-width footer — all without a single line number.
This single declaration places the item spanning from row line 1 to row line 3 and column line 1 to column line 3 — a 2x2 block — equivalent to writing grid-row: 1 / 3; grid-column: 1 / 3; separately.
.hero {
grid-column: 1 / -1; /* span from the first line to the very last line */
grid-row: 1;
}.page {
display: grid;
grid-template-columns: 220px 1fr 220px;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header header"
"nav main aside"
"footer footer footer";
min-height: 100vh;
gap: 16px;
}
.site-header { grid-area: header; }
.site-nav { grid-area: nav; }
.site-main { grid-area: main; }
.site-aside { grid-area: aside; }
.site-footer { grid-area: footer; }.featured-card {
grid-area: 1 / 1 / 3 / 3; /* row-start / column-start / row-end / column-end */
}Line-based span vs named area for the same layout
Both approaches produce the identical visual layout — grid-template-areas is simply a more readable way of writing the same placement.
Line-based: Named areas:
col lines: 1 2 3 4 grid-template-areas:
+--+-----+ "sidebar header"
row 1 | | H | "sidebar main"
+--+-----+ "sidebar footer"
row 2 |S | M |
+--+-----+ H = grid-column: 2; grid-row: 1;
row 3 | | F | S = grid-column: 1; grid-row: 1 / 4;
+--+-----+ M = grid-column: 2; grid-row: 2;Important Rules
In grid-column / grid-row, the end line is exclusive — it marks a boundary, not a track the item occupies span <count> is measured from the start line and is often easier than computing an end line manually grid-area's 4-value shorthand order is row-start / column-start / row-end / column-end
Every named area in grid-template-areas must form a single unbroken rectangle
Every quoted row string in grid-template-areas needs the same number of area names as every other row
Real-world usage
Named grid-template-areas has become the go-to approach for whole-page layouts and dashboard shells because it doubles as living documentation — a new developer can understand the page structure just by reading the CSS. Line-based placement with span remains the better tool for dynamic or repetitive layouts, like masonry-style galleries, where areas would need a unique name per item.
grid-template-areas: "header header" "nav main extra";
grid-template-areas: "header header header" "nav main extra";
Every row string must declare the same number of columns as every other row — here the first row only has 2 names while the second has 3, which is invalid and will be ignored by the browser..card { grid-column: 1 / 3; } /* developer thinks this spans 3 columns */.card { grid-column: 1 / span 3; } /* or: grid-column: 1 / 4; */ grid-column: 1 / 3 spans from line 1 to line 3, which covers only 2 column tracks, not 3, because the end line is exclusive. To actually span 3 tracks starting at line 1, either use span 3 or end at line 4.
[Choose the Correct Syntax] You want a grid item to start at column line 2 and span exactly 3 column tracks. Which declaration achieves this correctly? A. grid-column: 2 / 3; B. grid-column: 2 / span 3; C. grid-column: span 2 / 3; D. grid-column: 3 / 2;
B. grid-column: 2 / span 3; — grid-column: 2 / span 3 starts the item at column line 2 and spans 3 tracks forward from there (ending at line 5). '2 / 3' would only span 1 track, since the end line is exclusive and only 1 track separates lines 2 and 3.
Rebuild a simple blog layout using named grid-template-areas with a header spanning the full width, a main content area, a sidebar to its right, and a footer spanning the full width..blog { display: grid; grid-template-columns: 2fr 1fr; grid-template-areas: "header header" "content sidebar" "footer footer"; }.blog-header { grid-area: header; }.blog-content { grid-area: content; }.blog-sidebar { grid-area: sidebar; }.blog-footer { grid-area: footer; }
Define grid-template-columns for main and sidebar, then draw three or four rows in grid-template-areas using . if any cell should stay empty.