Topic 8.3
Placing Items
In one line
You place a grid item by naming the lines it starts and ends on (grid-column: 1 / 3), by saying how many tracks it spans (span 2), or by counting from the end with negative numbers (1 / -1); items may overlap, and later items or a higher z-index paint on top.
Think of it like this
A school timetable. The days are columns and the periods are rows. A double maths lesson starts at period 2 and ends before period 4: it covers two boxes. Lunch spans every day, from the first column to the last. You describe each lesson by where it starts and where it ends, and that's exactly how you place a grid item.
Words you'll meet
New words in this topic, in plain English. Come back here whenever one feels fuzzy.
- Line number
- The number of a grid line, counting from 1 at the start. A grid with N tracks has N + 1 lines.
- `grid-column` / `grid-row`
- Shorthands for where an item starts and ends:
grid-column: 1 / 3. - `grid-area` (placement)
- All four lines at once: row-start / column-start / row-end / column-end.
- `span`
- How many tracks an item covers, instead of naming its end line:
span 2. - Negative line
- A line counted from the end of the explicit grid:
-1is the last line. - Overlap
- Two or more items covering the same cells. The later or higher
z-indexone shows on top. - Named line
- A grid line given a name in square brackets, like
[content-start], so you can place items by name. - `z-index`
- A number that decides which overlapping item is drawn on top. Higher is closer to you.
Step by step
01Count the lines first
Draw the grid in your head and number its lines. Four equal columns give column lines 1, 2, 3, 4, 5. The last line is also -1, the first is also -5.
02Place an item by start and end
The header covers columns 1 to 4: it starts on line 1 and ends on line 5. 1 / -1 says the same thing and keeps working if you add a column later.
.header {
grid-column: 1 / -1;
}03Let an item span without fixing its position
A featured photo should be twice as big, but you don't care where it lands. span 2 in both directions makes it a 2 by 2 block; auto-placement finds the first free spot that fits.
.featured {
grid-column: span 2;
grid-row: span 2;
}04Use grid-area for all four lines
grid-area: 2 / 1 / 4 / 3 is row 2 to 4, column 1 to 3. Read it as top / left / bottom / right.
.sidebar {
grid-area: 2 / 1 / 4 / 3;
/* same as: grid-row: 2 / 4; grid-column: 1 / 3; */
}05Overlap two items
Put the photo and the caption in the same cells. The caption comes later in the HTML, so it's drawn on top. Give it align-self: end (Topic 8.5) to sit at the bottom of the photo.
.hero { display: grid; }
.hero img,
.hero .caption {
grid-area: 1 / 1;
}
.hero .caption {
align-self: end;
}06Name lines for readable placement
A common article layout: text stays in a readable middle column, but images can break out to full width. Named lines make the intention obvious.
.article {
display: grid;
grid-template-columns:
[full-start] 1fr [content-start] minmax(0, 60ch) [content-end] 1fr [full-end];
}
.article > * { grid-column: content; }
.article > .wide { grid-column: full; }Try it yourself
- 1
Move c up
In the first example, change
.ctogrid-column: 2 / -1; grid-row: 2;. Predict whether anything changes (no: it was already in row 2). Now change it togrid-row: 1. Predict wherea,banddgo, then check: placed items go first, soctakes row 1 and the others flow around it. - 2
Switch to grid-area
Rewrite
.aas onegrid-areadeclaration that keeps it in row 1, columns 1 to 2. (Answer:grid-area: 1 / 1 / 2 / 3.) Run: the console line forashould be the same. - 3
Move the badge
In the second example, move the badge to the bottom-left cell with
grid-area: 2 / 1. Predict which is on top at the badge now: the badge or the caption? (The badge, because of itsz-index.)
Code & diagrams
`b` lands right after `a` because auto-placement moves forward. `c` must start on line 2, which is already used in row 1, so it drops to row 2. `d` has no free cell left in row 2 (the cursor is past `c`), so it starts row 3.
Preview
Console
Nothing logged yet.Expected console output
a 1 / 3 x=0 y=0 w=200
b span 2 / auto x=200 y=0 w=200
c 2 / -1 x=100 y=40 w=300
d auto / auto x=0 y=80 w=100The caption is later in the HTML than the photo, so it's on top. The badge comes **first** in the HTML, so it would be hidden under the photo, but `z-index: 1` lifts it. Delete the `z-index` line and run: the badge disappears behind the photo.
Preview
Console
Nothing logged yet.Expected console output
at the centre of .caption the top element is caption
at the centre of .badge the top element is badge
photo grid-area: 1 / 1 / 3 / 3`grid-column: content` uses the lines named `content-start` and `content-end`. In the small grid, `column 5` doesn't exist, so the browser adds two 30px implicit columns. `1 / -1` still spans only the three explicit columns (150px).
Preview
Console
Nothing logged yet.Expected console output
text width: 240 wide width: 300
small grid tracks: 50px 50px 50px 30px 30px
1 / -1 width: 150Break it on purpose
Errors are the best teachers. Make each change, read the error, guess what went wrong, then reveal the answer.
Break #1
Count tracks instead of lines
To make a header cover all 3 columns, write grid-column: 1 / 3.
Break #2
Expect -1 to reach implicit columns
In a grid with no grid-template-columns and grid-auto-flow: column, give a heading grid-column: 1 / -1.
Break #3
Visual order that fights the HTML
Reorder a form's fields visually by placing the last input in row 1 with grid-row: 1.
Myth vs fact
Myth
grid-column: 1 / 3 covers three columns.
Fact
It covers two: from line 1 to line 3. The end number is a line, not a count.
Myth
z-index only works with position: relative or absolute.
Fact
Grid items (and flex items) are stacked by z-index even when they are position: static.
Myth
Placing an item on a line that doesn't exist hides it.
Fact
The browser adds implicit tracks so the line exists, and the item shows up there.
Pro corner
Extra depth for experienced readers. New to this? Skip it for now and come back later.
- ▸
The placement algorithm runs in a fixed order: items with a definite row and column, then items locked to a row, then the implicit grid's columns are settled, then the rest are auto-placed with a cursor. In sparse mode the cursor only moves forward, which is why item
dabove skipped the free cell at row 2, column 1. - ▸
When you place with a name that appears several times (
repeat(3, [col] 1fr)),grid-column: col 2means "the second line named col".span col 2spans until the second such line. If the name doesn't exist at all, every implicit line is assumed to have it, which can create surprising implicit tracks. - ▸
Overlapping grid items create stacking order from
z-indexand DOM order without needing positioning. A grid item with az-indexother thanautoalso creates a stacking context, like a positioned element, so its children can't escape above a sibling item (Phase 6, Topic 6.3). - ▸
order(shared with Flexbox) changes auto-placement order and painting order but not focus order. CSS Display Level 4'sreading-flowproperty, now shipping in Chromium, lets the browser follow the visual grid order for focus and screen readers; until it is supported everywhere, keep the HTML in a sensible order.
Remember this
- 1
Every item has four placement properties: **
grid-column-start,grid-column-end,grid-row-startandgrid-row-end. Each takes a line number**.grid-column-start: 2; grid-column-end: 4;means "start on column line 2, end on column line 4": the item covers columns 2 and 3. Remember you count lines, not tracks: a 4-column grid has lines 1 to 5. - 2
The shorthands are **
grid-columnandgrid-row**, written asstart / end:grid-column: 2 / 4andgrid-row: 1 / 3. If you give only one number (grid-column: 2), the item starts there and spans one track. **grid-areais the shortest form, with four values in the order row-start / column-start / row-end / column-end** (top, left, bottom, right: the opposite of the clockwise order ofmargin). - 3
**
span** describes size instead of an end line:grid-column: span 2means "cover two columns, wherever auto-placement puts me", andgrid-column: 3 / span 2means "start on line 3 and cover two columns". Spans are perfect for galleries where some pictures are bigger, because you don't have to know where they will land. - 4
Negative numbers count from the end of the explicit grid:
-1is the last line,-2the one before. Sogrid-column: 1 / -1stretches an item across the whole explicit grid however many columns there are: the standard way to write a full-width banner or a heading row. Careful: negative numbers count only the explicit grid (the tracks you wrote), not implicit tracks the browser added. - 5
If you place an item on a line that doesn't exist (
grid-column: 7in a 3-column grid), the browser does not clip it. It adds implicit columns (sized bygrid-auto-columns) so the line exists. Items you place explicitly are put first; then auto-placement fills the remaining cells around them in order. An item with only a column given is put in the first row where those columns are free. - 6
Items can overlap: give two items the same lines and they share the cells. By default the one later in the HTML paints on top. **
z-indexworks on grid items without**position: relative(unlike normal blocks, Phase 6), soz-index: 1lifts an item above its neighbours. Overlap is how you put a caption over a photo without absolute positioning: both items stay in the grid and both affect the track sizes. - 7
You can also name lines inside the template with square brackets:
grid-template-columns: [full-start] 1rem [content-start] 1fr [content-end] 1rem [full-end]. Thengrid-column: content-start / content-endis easier to read than2 / 3, and names ending in-startand-endlet you writegrid-column: contentfor short. A line can have several names, like[sidebar-end main-start].
Explain it without notes
Explain the difference between grid-column: 2 / 4 and grid-column: 2 / span 2, and when you'd use span alone.
What does grid-column: 1 / -1 do, and when doesn't it reach the last visible column?
In what order does grid-area: 1 / 2 / 3 / 4 give its four lines?
How can two grid items overlap, and how do you control which one is on top?
Practice
In a 3-column grid, make the first item a full-width header and the last item a full-width footer, whatever the number of columns.
Make the featured photo in a 4-column gallery cover two columns and two rows, starting in the top-left corner.
Put a text label over the bottom of an image using grid overlap, with no position: absolute.
Trade-offs
- ↔
Explicit line numbers give exact control but break when you add or remove a column;
span,-1and named lines survive template changes better. - ↔
Overlapping grid items keep everything in layout (both items size the track) unlike absolute positioning, but the overlap is purely visual; make sure text over images has enough contrast.
Done when you can
I can place an item with
grid-column,grid-rowandgrid-area, counting lines correctly.I can use
spanand negative lines like1 / -1.I can predict where auto-placed items go around explicitly placed ones.
I can overlap items and control which is on top with
z-index.I can name lines and place items by name.