In CSS Grid, what does `grid-template-columns: subgrid` do, and how does it differ from giving a nested grid its own column tracks?
answer
- nested grid stops being independent
- tracks come from the parent
- span count decides track count
- must be a grid item and a grid container
- rows and columns subgrid separately
basics
~20 ssubgrid makes a nested grid reuse its parent's tracks across the area the item spans, so its own children align to the parent's grid lines. An independent nested grid defines fresh tracks that align to nothing outside itself.
solid answer
~50 s`subgrid` is a value of `grid-template-columns` or `grid-template-rows`, set on an element that is both a grid item of an outer grid and a grid container itself. On that axis it stops defining tracks of its own and instead adopts the parent's tracks — exactly the ones its own grid area spans. So an item placed with `grid-column: span 3` and `grid-template-columns: subgrid` gets three columns whose sizes and positions are the parent's. Its children then land on the *parent's* lines, which is what lets content in sibling nested grids line up. A normal nested grid is fully independent: its `1fr` tracks are computed from its own content box, so two siblings with different content get different track sizes and nothing lines up across them. The two axes are independent — you can subgrid rows and still size columns yourself.
code
css · 17 lines.parent {
display: grid;
grid-template-columns: 8rem 1fr 4rem;
gap: 1rem;
}
.subgridded {
grid-column: 1 / -1;
display: grid;
grid-template-columns: subgrid;
}
.independent {
grid-column: 1 / -1;
display: grid;
grid-template-columns: 8rem 1fr 4rem;
}go deeper
Be able to say that a grid inside a grid normally starts fresh, and that subgrid is the value that makes the inner one reuse the outer grid's tracks instead.
Explain the two prerequisites — grid container and grid item — and that the number of inherited tracks equals the number of parent tracks the item spans, per axis.
Show judgment about when shared lines are actually worth it, and be ready to debug a subgrid that silently did nothing because the span, the display value, or an intermediate wrapper was wrong.
Own the call about where alignment contracts live in a component library: which lines are a shared layout concern the outer grid must define, and which stay private to a component so it remains portable.
## The problem subgrid solves CSS Grid gives you a two-dimensional grid, but before subgrid that grid stopped at the grid container's direct children. If a grid item was itself a grid container, it started a brand-new, unrelated grid. Its tracks were computed from its own content, in its own content box. Two sibling items could each contain a heading and a body, and the boundary between them would sit at a different vertical position in each one, because each nested grid sized its rows from its own content. `subgrid` removes that isolation on a chosen axis. ## What the value actually means `subgrid` is a value of `grid-template-columns` and `grid-template-rows`. Two conditions must hold for it to do anything: 1. The element must be a grid container — `display: grid` or `display: inline-grid`. 2. That same element must itself be a grid item of an outer grid container. If there is no parent grid, `subgrid` behaves as `none`, so the element simply has no explicit tracks on that axis and everything falls into implicit tracks. When both conditions hold, the element does not create tracks on that axis. Instead it adopts the parent grid's tracks that its own grid area spans. The count is decided entirely by the span: ```css .parent { display: grid; grid-template-columns: 8rem 1fr 4rem; } .child { grid-column: 1 / -1; /* spans all three parent columns */ display: grid; grid-template-columns: subgrid; /* therefore has three columns */ } ``` `.child` now has exactly three columns, sized `8rem`, `1fr` and `4rem` — and positioned at the parent's line positions, not recomputed. A grandchild placed in the second column starts and ends exactly where the parent's second column does. If the item had spanned only two parent columns, the subgrid would have two columns. ## Per-axis, and mixable The two axes are independent. This is a common shape: ```css .card { display: grid; grid-row: span 3; grid-template-rows: subgrid; /* rows come from the parent */ grid-template-columns: minmax(0, 1fr) auto; /* columns are the card's own */ } ``` Rows are inherited so that content aligns across sibling cards; columns are defined locally because nothing outside the card needs to align to them. ## Sizing flows both ways Subgrid is not a one-way read of the parent's numbers. The subgrid's own items contribute their intrinsic size to the parent's track sizing, just as the subgrid's direct content would. So if the parent has an `auto` row and a subgridded card puts a tall paragraph in it, that parent row grows — and every sibling subgrid on that row grows with it. That mutual contribution is precisely why alignment across siblings works: all of them are measuring against one shared set of tracks. ## Independent nested grid, by contrast ```css .card { display: grid; grid-template-rows: auto 1fr auto; } ``` This card has three rows sized from *its own* content, inside its own content box. It is a perfectly good layout for the card in isolation, and it does guarantee the footer sits at the bottom of that card. What it cannot do is coordinate with a sibling card: if one card's heading wraps to two lines and another's does not, the row boundaries inside the two cards sit at different heights. Choosing between them is a scope question — does anything *outside* this box need to align to these lines? If yes, subgrid; if no, an independent nested grid is simpler and has no span requirements. ## Practical details that bite - The span is the source of truth for track count. Forgetting `grid-row: span 3` leaves the subgrid with a single row, and everything piles into it or into implicit tracks. - Padding or a border on the subgrid box insets its track area from the grid area, so its tracks no longer sit exactly on the parent's lines. Put the padding on the grandchildren instead when exact alignment matters. - Gutters come from the parent by default, and line names are inherited too, so you can place grandchildren using names declared on the outer grid. ## Support Subgrid shipped in Firefox 71, Safari 16, and Chrome/Edge 117 (September 2023), so it is available across all current major browsers; only genuinely old browser targets need a fallback. Feature-detect with `@supports (grid-template-columns: subgrid)` when your support matrix still includes them.
- What happens if you set `grid-template-columns: subgrid` on an element that is not a grid item?It computes to `none`. With no parent grid to inherit from, the element has no explicit columns at all, so its children fall into a single implicit column. This is the usual cause of a subgrid that "does nothing": the element is a grid container but its own parent is not a grid, or an intermediate wrapper broke the item relationship.
- How does a subgrid affect the parent's track sizes?Its items contribute to them. A subgridded item's children participate in sizing the parent's tracks the same way ordinary content would, so an `auto` parent track grows to fit the tallest contribution from any subgrid on it. That two-way relationship is what makes sibling subgrids agree on a shared line position.
- Can one element subgrid rows while defining its own columns?Yes — the two axes are fully independent. `grid-template-rows: subgrid` with `grid-template-columns: minmax(0, 1fr) auto` is a normal pattern: the rows are shared with the outer grid so content lines up across siblings, while the columns are local because nothing outside the element needs to align to them.
An independent nested grid is a page ruled with its own margins; subgrid is tracing paper laid over the parent's ruling so every sheet shares the same lines.
saying these in an interview costs you the question
- Thinking any nested grid automatically inherits the parent's tracks
- Setting subgrid without spanning multiple parent tracks
- Believing subgrid works on any descendant, not just a grid item
- Assuming subgrid must apply to both axes at once
- Claiming subgrid is still unsupported in Chrome