LEARNING OBJECTIVES ⌵
- Position grid items using
grid-column-start,grid-column-end,grid-row-start, andgrid-row-end. - Leverage the
spankeyword for relative track spanning. - Utilize negative line indices (such as
1 / -1) to span full explicit grid widths. - Overlap multiple grid items in the same grid cells and manage stacking contexts with
z-index.
📖 The Mental Model & Story (Intuitive Foundation)
Imagine an architect's graph paper ruled with bold blue coordinate lines numbered 1, 2, 3, 4, 5 along the top edge.
If you want to paste a photograph that starts at the 2nd line and ends at the 4th line, you specify the line boundaries: grid-column: 2 / 4.
Alternatively, if you know the photo is 2 columns wide, you can say: "Start at line 2 and span across 2 columns" (grid-column: 2 / span 2).
Now imagine you want to place a translucent title sticker directly on top of that photograph. In traditional CSS, you would have to break the sticker out of the document flow with position: absolute, calculating parent relative offsets. In CSS Grid, you simply tell the sticker to occupy the exact same line coordinates as the photograph, and use z-index to decide which element sits on top!
Technical Deep Dive & Specifications
Grid Line Coordinate System
Grid lines are numbered starting at 1 from the start edge (left in LTR languages, right in RTL languages) and -1 from the end edge.
Positive Lines: 1 2 3 4
+---------------+---------------+---------------+
| Col 1 | Col 2 | Col 3 |
+---------------+---------------+---------------+
Negative Lines: -4 -3 -2 -1
/* Longhand Properties */
.item {
grid-column-start: 1;
grid-column-end: 3;
grid-row-start: 2;
grid-row-end: 4;
}
/* Shorthand Properties (Recommended) */
.item {
grid-column: 1 / 3; /* start / end */
grid-row: 2 / 4; /* start / end */
}
The 4-Value grid-area Coordinate Shorthand
When grid-area is used with numbers rather than a name, it follows a specific 4-value order:
$$\text{grid-area: } \langle\text{row-start}\rangle \text{ / } \langle\text{col-start}\rangle \text{ / } \langle\text{row-end}\rangle \text{ / } \langle\text{col-end}\rangle;$$
/* Equivalent to: grid-row: 1 / 3; grid-column: 2 / 4; */
.item {
grid-area: 1 / 2 / 3 / 4;
}
(Notice the order: row-start / col-start / row-end / col-end — counter-clockwise from top).
The span Keyword
Instead of specifying the terminating line number, span declares the number of tracks an item should cover:
/* Start at line 2 and cover 3 columns */
.item-a {
grid-column: 2 / span 3;
}
/* Auto-placed start line, but span 2 columns */
.item-b {
grid-column: span 2;
}
/* End at line 4, spanning backwards 2 columns */
.item-c {
grid-column: span 2 / 4;
}
Negative Line Coordinates (-1)
Line -1 always targets the last explicit grid line.
/* Spans from the first column line to the very last column line */
.full-bleed-banner {
grid-column: 1 / -1;
}
⚠️ Important Spec Rule: Negative line numbers only refer to the explicit grid defined by
grid-template-*. They cannot reference tracks created dynamically in the implicit grid.
Item Overlapping & z-index Stacking
CSS Grid allows multiple items to share identical or overlapping track coordinates without position: absolute.
.hero-container {
display: grid;
grid-template-columns: repeat(12, 1fr);
grid-template-rows: 400px;
}
.hero-background-image {
grid-column: 1 / -1; /* Spans all 12 columns */
grid-row: 1 / 2;
z-index: 1;
}
.hero-floating-card {
grid-column: 3 / 9; /* Overlaps columns 3 through 8 */
grid-row: 1 / 2;
z-index: 2; /* Renders on top of the image */
align-self: center; /* Centers vertically within the row */
}
💻 Interactive Code Playground
Starter Code
Line-by-Line Code Breakdown
- Line 26 (
grid-template-columns: repeat(6, 1fr)): Creates a 6-column base grid. - Line 27 (
grid-template-rows: 100px 200px 100px): Creates 3 distinct row tracks. - Line 37 (
grid-column: 1 / -1; grid-row: 1 / 3;): The banner spans across all 6 columns (lines 1 to 7) and covers rows 1 and 2. - Line 47 (
grid-column: 2 / span 4; grid-row: 2 / 4;): The card starts at column line 2 and spans 4 columns, while starting at row line 2 and ending at row line 4, creating an elegant visual overlap. - Line 53 (
z-index: 2): Places the card in front of the background banner without requiringposition: absolute.
Expected Browser Render Output
+-------------------------------------------------------------------------------+
| .hero-grid |
| [Line 1] [Line 2] [Line 3] [Line 4] [Line 5] [Line 6] |
| +-----------------------------------------------------------------+ [BADGE] |
| | HERO BANNER (grid-column: 1 / -1, grid-row: 1 / 3) | |
| | Cloud Infrastructure 2026 | |
| | +----------------------------------------+ | |
| | | FLOATING CARD | | |
| +----------------| (grid-column: 2 / span 4) |-------+ |
| | (grid-row: 2 / 4) | |
| +----------------------------------------+ |
+-------------------------------------------------------------------------------+🏋️ Hands-On Exercise
🎯 The Challenge: Build a Bento-Box Portfolio Grid
Instructions:
- Create a 3-column, 3-row grid container
.bento-gridwithrepeat(3, 1fr)columns and120pxrows. - Place Card 1 (Hero Item) to span Columns 1 to 3 (first 2 columns) and Rows 1 to 3 (first 2 rows) using
grid-column: 1 / 3andgrid-row: 1 / 3. - Place Card 2 (Tall Item) in Column 3, spanning Rows 1 through 3 (
grid-column: 3 / 4; grid-row: 1 / 3;). - Place Card 3 (Wide Footer) spanning all 3 columns in Row 3 (
grid-column: 1 / -1; grid-row: 3 / 4;).
🏁 Starter Code Sandbox
⚠️ Common Pitfalls
- Confusing Lines with Tracks: Writing
grid-column: 1 / 2expecting it to span 2 columns. Line 1 to Line 2 is only 1 column track wide. To span 2 columns, writegrid-column: 1 / 3orgrid-column: span 2. - Using
-1on Implicit Grids: Trying to usegrid-row: 1 / -1on a grid with implicit rows. Line-1only resolves to the end of the explicit grid declared ingrid-template-rows. - The 4-Value
grid-areaCoordinate Confusion: Misremembering the order ofgrid-area: 1 / 2 / 3 / 4. Remember it isrow-start / col-start / row-end / col-end.
💡 Pro Tips
- Negative Spanning: You can write
grid-column: span 3 / -1;to anchor an item to the right edge and span 3 columns leftwards. - Zero-Height Overlay Hacks Eliminated: Before Grid, overlapping required
position: relativeparents andposition: absolutechildren with matching heights. With Grid, setting overlapping items in the same track causes the row height to automatically match the tallest item!
📌 Key Takeaways
grid-column: start / endandgrid-row: start / endplace items along explicit line coordinates.span Nspecifies relative track coverage without hardcoding terminating line numbers.- Negative line index
-1represents the final explicit grid line (grid-column: 1 / -1spans full width). - Multiple items can occupy identical grid cells, ordered along the z-axis using
z-index. - Grid-based overlapping does not remove elements from the flow, preserving automatic parent height calculations.
- --