Section 2 · Layout That Holds Up
Grid: Areas, auto-fit and minmax()
18 min3 min readCode playground
Lesson at a glance
Lay out a page with named grid-template-areas and build a speaker grid that picks its own column count with repeat(auto-fit, minmax()).
- 1Draw the page with template areas
- 2The fr unit and its hidden minimum
- 3A speaker grid that counts its own columns
- 4Your turn
No video here — just the real thing: a written lesson, runnable examples, a quiz and practice.
Flexbox lays things out in one direction and lets each line make its own decisions. That’s perfect for a row of filters and wrong for Waypoint’s speaker grid, where every card in a column should line up with the cards above and below it. When you need rows and columns to agree, you want grid.
This lesson builds two layouts on the schedule page: the page shell, with named areas, and the speaker grid, which decides its own number of columns.
Draw the page with template areas
The schedule page has a header across the top, a filter sidebar and the main content. With grid-template-areas you draw that layout directly:
.page {
display: grid;
grid-template-columns: 14rem minmax(0, 1fr);
grid-template-areas:
"header header"
"filters main";
gap: 1.5rem;
}
.site-header { grid-area: header; }
.filters { grid-area: filters; }
.schedule { grid-area: main; }Each string is a row; each word inside it is a column. Repeating a name (header header) makes that area span both columns. A . marks an empty cell. Areas must be rectangles: an L-shape is invalid and the whole declaration is dropped.
The pay-off comes when the layout changes. On narrow screens the filters should sit above the sessions, so you redraw the strings instead of moving markup:
@media (width < 48rem) {
.page {
grid-template-columns: minmax(0, 1fr);
grid-template-areas:
"header"
"filters"
"main";
}
}The fr unit and its hidden minimum
fr divides the free space in the grid after fixed tracks and gaps are subtracted. Two 1fr columns in a 600px grid with a 20px gap are 290px each.
There’s a catch you’ll meet sooner or later: 1fr is shorthand for minmax(auto, 1fr), and auto as a minimum means “at least the content’s min-content width”. Put a long unbroken URL or a code block in one column and it widens, stealing space from the other. That’s why the page shell above uses minmax(0, 1fr): it lets the main column shrink below its content, and any overflow is handled inside it (with overflow-x: auto on the code block, for instance). It’s the grid cousin of the min-width: 0 fix from the previous lesson.
A speaker grid that counts its own columns
Waypoint has 23 speakers. On a phone they should stack; on a laptop, four or five across. One declaration handles every width:
.speakers {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
gap: 16px;
}
.speaker.featured {
grid-column: 1 / -1;
}Read it inside out. minmax(180px, 1fr) says each column is at least 180px and at most an equal share of the free space. repeat(auto-fit, …) asks the browser to create as many such columns as fit. In a 640px container with 16px gaps, three 180px columns fit (three columns plus two gaps is 572px) and four don’t, so you get three columns, each stretched to about 203px.
grid-column: 1 / -1 makes the keynote speaker span from the first line to the last, whatever the column count. Negative line numbers count from the end of the explicit grid.
The difference between auto-fit and auto-fill only shows when there are fewer items than columns. auto-fill keeps the empty tracks, so two speakers stay card-sized and leave a gap. auto-fit collapses empty tracks to zero, so the two speakers stretch across the row. For a speaker grid that’s sometimes nearly empty (day two has only four speakers), pick based on the design: auto-fill for consistent card widths, auto-fit for a full row.
Your turn
The exercise gives you the page shell and the speaker grid with hard-coded columns. Name the areas, switch the speakers to auto-fit, and make the keynote span the whole row. The checks resize the page to make sure the column count adapts. Next, you’ll make the contents of grid cards line up across cards with subgrid.
Key takeaways
grid-template-areaslets you draw the layout as ASCII art, and rearranging the page for another screen size means redrawing the strings, not moving markup.repeat(auto-fit, minmax(12rem, 1fr))creates as many columns as fit and stretches them to fill the row, with no media queries.auto-fillkeeps empty tracks when there are few items, whileauto-fitcollapses them so the items stretch to fill the row.1frhas an automatic minimum of the content size; useminmax(0, 1fr)when a track must be allowed to shrink below its content.