Complex Grids and Nested Layout Patterns
Name the page frame with grid areas, nest grids safely, and line up card contents across a row with subgrid. After this, you stop faking alignment with fixed heights.
Course content
Sign in to save your progress.
-
Architecture That Scales
-
Modern CSS Without a Framework Crutch
-
Cascade Layers and Specificity You Control
-
-
-
Layout Systems for Real Sites
-
Complex Grids and Nested Layout Patterns
-
Container Queries When the Component Is the Breakpoint
-
-
-
Motion and Interaction Done Right
-
Transitions and Animations That Don't Annoy People
-
prefers-reduced-motion and Respecting the User
-
-
-
Performance and Delivery
-
Critical CSS and What Blocks First Paint
-
Font Loading Without Layout Jump
-
Responsive Images: srcset, sizes and Lazy Load
-
-
-
Ship and Maintain
-
Design Tokens and Theming Without Duplicating Everything
-
CSS That Survives a Redesign
-
Audit Accessibility and Visual Regressions Before Launch
-
-
- Final Check: HTML and CSS Advanced
Skip ahead: If you already name grid areas for page frames and use subgrid to line up the insides of cards, skip to "Common mistakes", then continue.
Flexbox handles one direction. A real page has two: columns and rows that have to agree with each other. Grid is the tool for that, and the part most people never get to is nesting. A card grid inside a page grid works, but the card contents do not line up across a row unless you tell the children to share their parent's rows. That is what subgrid is for.
Name the page frame
.page {
display: grid;
grid-template-columns: 14rem minmax(0, 1fr);
grid-template-areas:
"header header"
"nav main"
"footer footer";
min-height: 100vh;
}
.page > header { grid-area: header; }
.page > nav { grid-area: nav; }
.page > main { grid-area: main; }
.page > footer { grid-area: footer; }
@media (max-width: 40rem) {
.page {
grid-template-columns: minmax(0, 1fr);
grid-template-areas: "header" "nav" "main" "footer";
}
}
The picture of the page is in the CSS, so the next developer can read it. On a phone you redraw the picture. You do not touch the HTML. minmax(0, 1fr) matters: a plain 1fr track will not shrink below the width of its widest child, and a wide table or code block pushes the whole page sideways.
Nest a grid inside a grid area
main is a grid item of .page. Inside it you are free to start a new grid. The inner grid is independent. Its tracks know nothing about the outer ones. That is fine for a card list. It is not fine when cards need matching internals.
Line up card internals with subgrid
.products {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
gap: 1rem;
}
.product {
display: grid;
grid-row: span 3;
grid-template-rows: subgrid;
gap: 0.5rem;
}
Each card takes three row tracks from the parent and hands them to its title, price and button. I tested three products in a three-column grid in Chrome 154, one with a very long name. Without subgrid, the price tops were 76, 104 and 76 pixels down the page, so the middle card was out of line, and the buttons came out at 116, 130 and 116. With subgrid, the price tops were all 277 and the buttons all 303. The long title makes the whole row taller, and the other cards follow.
⚠ Warning: Subgrid only helps cards in the same row. Once the list wraps, each new row has its own tracks, which is what you want. Do not try to align cards in different rows.
When to use which
- Flexbox: one direction, content decides the size (toolbars, tags, button groups).
- Grid: the layout decides the size (page frames, galleries, forms with labels in one column and fields in another).
- Subgrid: a child must follow its parent's tracks, as with card internals, or form rows inside a fieldset that line up with the page.
Common mistakes
- Using
1frwhereminmax(0, 1fr)is needed, then wondering why a long URL widens the page. - Writing
grid-row: span 3withoutgrid-template-rows: subgrid. The card takes three rows but its children do not share them. - Nesting five wrapper divs where one
grid-areawould do. - Hiding source-order problems with
orderorgrid-area. Keyboard users follow the HTML order, not the picture.
💡 Tip: When a layout breaks, open DevTools and click the grid badge on the container. It draws the tracks and the line numbers, so you see which child sits where.
What happens if you skip this
You fake alignment with fixed heights and min-height guesses. They work until a translation, a longer product name or a bigger font makes one card taller, then the buttons fall out of line again.
Try it
Take a card list with uneven title lengths. First give it a fixed min-height on the title, then replace that with subgrid, and change the longest title to something twice as long.
Which of those two versions can you leave alone in six months?
About
Name the page frame with grid areas, nest grids safely, and line up card contents across a row with subgrid. After this, you stop faking alignment with fixed heights.
- Duration
- 5 min
- Last update
- 08/06/2026
Comments (0)
Sign in to commentNo comments yet.