๐ Grid Item Placement and Alignment
The container sets the stage; the items take their marks. This lesson is all about the child side of Grid โ pinning items to exact lines, spanning tracks, aligning each item inside its cell, reordering visually, and even layering items on top of one another.
๐ฏ Learning Objectives
By the end of this lesson, you will be able to:
- Place items by line number, negative line, named line, and the
spankeyword - Use
grid-areaboth to assign named areas and as the four-value placement shorthand - Combine auto-placement with explicit placement in one grid
- Align individual items with
justify-self,align-self, andplace-self - Reorder items visually with
orderand stack overlapping items withz-indexโ and know the accessibility caveats
Estimated Time: 40โ50 minutes โข Difficulty: Intermediate
Hands-on: Build a magazine-style article layout with a spanning hero, a pull-quote, and a sidebar.
In This Lesson
Lines, Areas & Numbering
Every item you place references grid lines โ the numbered dividers between tracks. Numbering starts at 1 on the left/top and, crucially, also runs backwards from the end: -1 is the last line, -2 the second-to-last, and so on. That backward numbering is your best friend when the track count is dynamic.
grid-column: 1 / -1 always spans the full width, however many columns exist.A grid area is any rectangle bounded by four lines: a single cell, a run of cells, or a region named through grid-template-areas. Think of areas as rooms โ each has defined walls, and some are bigger than others.
Line-Based Placement
Four long-hand properties pin an item to specific lines; two shorthands express the same thing more compactly.
/* Long-hand */
.item {
grid-row-start: 1;
grid-row-end: 3; /* occupies rows between line 1 and line 3 */
grid-column-start: 2;
grid-column-end: 4;
}
/* Shorthand: start / end */
.item {
grid-row: 1 / 3;
grid-column: 2 / 4;
}
Negative lines for end-anchored items
Because -1 is always the final line, negative numbers let you anchor to the end without knowing the track count:
/* Full-width banner, no matter how many columns */
.banner { grid-column: 1 / -1; }
/* Bottom-right cell of any grid */
.badge {
grid-row: -2 / -1;
grid-column: -2 / -1;
}
Named lines
If the container named its lines (or you used grid-template-areas, which creates *-start/*-end names for free), place items with words:
.header { grid-column: sidebar-start / content-end; }
.sidebar { grid-row: main-start / footer-end; }
The span Keyword
Often you care how many tracks an item covers, not exactly where it ends. The span keyword says "start here, then cover N tracks":
.feature {
grid-column: 1 / span 3; /* start at line 1, cover 3 columns */
grid-row: 2 / span 2; /* start at line 2, cover 2 rows */
}
/* Span backwards from the end */
.tail { grid-column: span 2 / -1; } /* cover 2 columns, ending at the last line */
It's like asking a restaurant for "a table for four" instead of "table number 12" โ you state the size, not the exact spot. This keeps layouts resilient when the surrounding track count changes.
๐ก Shorthand for a single edge
Writing just grid-column: span 2 (no start line) lets the auto-placement algorithm choose the starting line, then reserves two columns from there โ handy inside auto-flowed galleries.
The grid-area Shorthand
grid-area wears two hats.
1) Assign a named area
.container {
display: grid;
grid-template-areas:
"header header header"
"sidebar content content"
"footer footer footer";
}
.header { grid-area: header; }
.content { grid-area: content; }
2) Place with four lines at once
As a pure placement shorthand, grid-area takes four values in a clockwise-ish order that trips everyone up at first:
/* grid-area: row-start / column-start / row-end / column-end */
.item { grid-area: 1 / 2 / 3 / 4; }
grid-area as top โ right โ bottom โ left: row-start, column-start, row-end, column-end.The four-value form is compact but hard to read; for anything complex, named areas or separate grid-row/grid-column declarations are kinder to the next developer.
Auto vs. Explicit Placement
You can mix both strategies in a single grid: pin the important items, and let the rest flow.
.gallery {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: 200px;
gap: 20px;
}
/* One explicitly placed hero */
.featured {
grid-column: 1 / 3; /* first two columns */
grid-row: 1 / 3; /* first two rows */
}
/* Everything else auto-places around it */
.gallery-item { /* no placement โ flows automatically */ }
It's like a restaurant with one reserved table (explicit) while other diners are seated wherever there's room (auto). The auto-placement algorithm โ steered by the container's grid-auto-flow โ fills the remaining cells, flowing around your pinned hero.
Per-Item Alignment
The container's justify-items/align-items set defaults for all items. Any single item can override them with the -self variants. By default items stretch to fill their cell.
| Property | Axis | Values |
|---|---|---|
justify-self | inline (โ) | start ยท center ยท end ยท stretch |
align-self | block (โ) | start ยท center ยท end ยท stretch |
place-self | both | align-self justify-self |
.item {
justify-self: end; /* push to the right of its cell */
align-self: center; /* center vertically in its cell */
place-self: center end; /* shorthand: align-self=center, justify-self=end */
}
justify-self positions an item along the row axis inside its cell. align-self does the same vertically.order & z-index
Reordering with order
Every grid item has order: 0 by default and paints in source order. Change the number to move an item visually without touching the HTML โ lower orders come first, and equal orders keep source order.
.promo { order: -1; } /* jump to the front */
.legal { order: 1; } /* drift to the back */
โ ๏ธ Accessibility caveat
order only changes the visual order. Keyboard tab order and screen-reader reading order still follow the DOM. A large gap between the two disorients keyboard and assistive-tech users. Use order for small tweaks, keep the source order sensible, and always test with the keyboard.
Layering with z-index
Items placed in overlapping cells stack. Unlike positioned elements, grid items obey z-index without needing position: relative:
.card { display: grid; grid-template: repeat(12, 1fr) / repeat(12, 1fr); }
.card-image { grid-area: 1 / 1 / 13 / 13; z-index: 1; }
.card-overlay { grid-area: 8 / 1 / 13 / 13; z-index: 2; }
.card-text { grid-area: 9 / 2 / 12 / 12; z-index: 3; color: #fff; }
Here an image fills the whole card, a gradient overlay covers its lower third, and the text sits on top โ three items sharing cells, layered by z-index. Perfect for hero cards, badges, and captions.
Hands-on Exercise
๐๏ธ Magazine-Style Article Layout
Objective: Use a 12-column grid to compose an article with a full-width headline and hero image, a narrower reading column, a pull-quote, and a sidebar โ then collapse it to one column on mobile.
Requirements
- A 12-column grid with a comfortable gap.
- Headline and hero image span the full width (
1 / -1). - Body text sits in a centered reading column (roughly columns 3โ11).
- A pull-quote spans a few left columns; a sidebar occupies the right, spanning two rows.
- Below 768px, every element collapses to a single column.
๐ก Hint
Set grid-template-columns: repeat(12, 1fr) and place each element with grid-column. Give the sidebar grid-row: span 2 and align-self: start so it doesn't stretch. In the mobile media query, set every element to grid-column: 1 / -1.
โ Solution
.article {
display: grid;
grid-template-columns: repeat(12, 1fr);
grid-auto-rows: minmax(min-content, auto);
gap: 20px;
padding: 30px;
}
.article-header { grid-column: 1 / -1; text-align: center; }
.article-image { grid-column: 1 / -1; }
.article-lead { grid-column: 3 / 11; font-size: 1.2em; }
.article-body { grid-column: 3 / 11; line-height: 1.6; }
.article-quote {
grid-column: 2 / 6;
align-self: center;
font-size: 1.4em;
font-style: italic;
border-left: 4px solid currentColor;
padding-left: 1rem;
}
.article-sidebar {
grid-column: 8 / 12;
grid-row: span 2;
align-self: start;
padding: 1rem;
border: 1px solid #ddd;
border-radius: 8px;
}
@media (max-width: 768px) {
.article { grid-template-columns: 1fr; }
.article > * { grid-column: 1; }
}
On desktop you get a rich, asymmetric editorial layout; below 768px it gracefully stacks into one readable column โ same HTML throughout.
Best Practices
โ Do
- Prefer
grid-column: 1 / -1for full-width items so they survive column-count changes. - Use named lines/areas for complex placement; line numbers for simple spans.
- Reach for
spanwhen you care about size, not the exact end line. - Let overlapping grid items layer with
z-indexโ nopositionhack required.
โ ๏ธ Don't
- Don't overuse
orderโ it divorces visual order from DOM order and hurts accessibility. - Don't forget the
grid-areavalue order is row-start / column-start / row-end / column-end. - Don't create accidental overlaps; double-check that placements don't collide unless you mean them to.
Summary & Quiz
๐ Key Takeaways
- Place items by line number, negative line (
-1= last), named line, orspan. grid-areaassigns a named area or sets four lines: row-start / column-start / row-end / column-end.- Explicit and auto placement coexist โ pin the heroes, flow the rest.
justify-self/align-self/place-selfoverride container alignment for a single item.orderreorders visually only (mind accessibility); overlapping items stack withz-index, nopositionneeded.
๐ฏ Quick Quiz
Question 1: Which declaration makes an item span the full width of a grid no matter how many columns it has?
Question 2: In grid-area: 1 / 2 / 3 / 4, what does the value 2 represent?
Question 3: What is the key accessibility concern with the order property?
๐ Further Reading
- MDN โ Line-based Placement
- CSS-Tricks โ Things I've Learned About CSS Grid
- Grid by Example โ Patterns
- MDN โ Box Alignment in Grid
๐ What's Next?
You've now completed the full CSS Grid toolkit โ container and items alike. Next we step back to the bigger picture with Responsive Design Philosophy, where these layout tools serve a mobile-first, content-driven strategy.
๐ Grid complete!
Container plus items means you can build essentially any modern layout. Time to zoom out and think about responsiveness as a whole.