CSS Subgrid Reference & Generator
Configure parent and child grid settings, generate subgrid CSS, and explore gap inheritance, named lines, and nested subgrid patterns
Parent Grid
Child Subgrid
Subgrid axis
Both axes use subgrid — inherits both column and row tracks
Preview — blue cells indicate the child's subgrid span
4-column parent · child spans 4 columns × 3 rows
Generated CSS
/* Parent grid — defines the tracks that subgrid children inherit */
.parent {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: auto 1fr auto;
column-gap: 16px;
row-gap: 12px;
}/* Child item — participates in parent's column and row tracks via subgrid */
.child {
grid-column: span 4;
grid-row: span 3;
display: grid;
grid-template-columns: subgrid;
/* column-gap: 16px is inherited — cannot override */
grid-template-rows: subgrid;
/* row-gap: 12px is inherited — cannot override */
}/* Grandchild items align to the inherited grid tracks */
.child > * {
/* Aligns to parent column lines automatically */
/* Aligns to parent row lines automatically */
}
/* Slot grandchildren into specific parent row tracks */
.child-header { grid-row: 1; }
.child-body { grid-row: 2; }
.child-footer { grid-row: 3; }Your card grid looks great — until you notice the card titles, descriptions, and buttons don’t align across columns. Card A has a short title, Card B has a three-line title, and now the descriptions start at different heights. You try min-height on the title — it works for two-line titles but breaks on three-line ones. The real fix is grid-template-rows: subgrid on the card, so it inherits the parent grid’s row tracks and all cards align at every row boundary. But the syntax and gap inheritance behavior aren’t obvious.
Why This Reference (Not the MDN Subgrid Docs)
MDN covers subgrid syntax but doesn’t show the card alignment problem, one-axis vs two-axis subgrid patterns, or gap inheritance gotchas. This reference demonstrates each pattern with interactive examples, covers named lines in subgrid, nested subgrids, and includes a generator for common layouts. Everything runs in your browser; no data is sent anywhere.
What Is CSS Subgrid?
CSS Subgrid is a feature of CSS Grid that lets a nested grid item inherit tracks from its parent grid instead of creating its own. Without subgrid, a nested display: grid element defines completely independent row and column tracks — it cannot align its internal items to the outer grid. Subgrid solves this by letting the child say “use the parent’s column tracks” or “use the parent’s row tracks.”
.parent {
display: grid;
grid-template-columns: repeat(4, 1fr);
column-gap: 16px;
}
.child {
grid-column: 1 / -1; /* span all 4 columns */
display: grid;
grid-template-columns: subgrid; /* adopt parent's 4 column tracks */
}
/* grandchild aligns to parent column lines automatically */
.grandchild-wide {
grid-column: 1 / 3;
}
The value subgrid on grid-template-columns or grid-template-rows means: “inherit the parent’s tracks for this axis.” The child does not resize those tracks — the parent remains in control of track sizing.
grid-template-columns: subgrid
When a grid item spans multiple parent column tracks and sets grid-template-columns: subgrid, its own column layout is identical to the spanned section of the parent grid. The column sizes and column gaps are both inherited.
.parent {
display: grid;
grid-template-columns: 200px 1fr 200px;
column-gap: 20px;
}
/* Child spans all 3 parent columns */
.child {
grid-column: 1 / -1;
display: grid;
grid-template-columns: subgrid;
/* column-gap: 20px is inherited automatically */
}
/* These grandchildren align to parent column lines */
.sidebar-left { grid-column: 1; }
.main-content { grid-column: 2; }
.sidebar-right { grid-column: 3; }
This removes the need to hard-code matching column values in nested elements — the child always stays in sync with the parent.
grid-template-rows: subgrid
Row subgrid enables the most requested CSS layout: cards with equal-height sections. Multiple card components in the same grid row can have their header, body, and footer areas align perfectly, regardless of how much content each card contains.
.card-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
/* Define 3 shared row tracks for all cards */
grid-template-rows: auto 1fr auto;
gap: 24px;
}
.card {
grid-row: span 3; /* participate in 3 parent row tracks */
display: grid;
grid-template-rows: subgrid; /* adopt parent's row tracks */
}
.card-header { grid-row: 1; } /* aligns across all cards */
.card-body { grid-row: 2; } /* stretches to fill — 1fr */
.card-footer { grid-row: 3; } /* aligns across all cards */
Without subgrid, you would have to use JavaScript to measure and set heights, or accept that footers would be at different vertical positions across cards.
One-Axis Subgrid
A grid item can subgrid on one axis while defining its own tracks on the other. This is the most common real-world pattern:
.parent {
display: grid;
grid-template-columns: repeat(3, 1fr);
column-gap: 20px;
}
.item {
grid-column: 1 / -1;
display: grid;
/* columns: inherit from parent — column-gap 20px also inherited */
grid-template-columns: subgrid;
/* rows: define independently — own row-gap is allowed */
grid-template-rows: auto 1fr auto;
row-gap: 8px;
}
When only one axis uses subgrid:
- Subgrid axis: inherits parent tracks and parent gap (cannot override)
- Non-subgrid axis: works like a regular nested grid — own track sizing, own gap
Named Grid Lines in Subgrid
Parent grid named lines are available inside the child’s subgrid context. The child can reference them directly without any extra syntax:
.parent {
display: grid;
grid-template-columns:
[sidebar-start] 200px
[content-start] 1fr
[aside-start] 200px
[aside-end];
}
.child {
grid-column: sidebar-start / aside-end;
display: grid;
grid-template-columns: subgrid;
/* Names sidebar-start, content-start, aside-start, aside-end are all accessible */
}
.child-main {
/* Use parent named lines directly */
grid-column: content-start / aside-start;
}
You can also add local names to inherited tracks by appending them after the subgrid keyword (though browser support for this extended syntax may vary):
.child {
grid-template-columns: subgrid [local-name];
}
Gap Inheritance in Subgrid
Gap inheritance is one of the most important — and sometimes surprising — aspects of subgrid:
| Axis | Parent gap | Subgrid child | Can child override? |
|---|---|---|---|
| Column | column-gap: 20px | grid-template-columns: subgrid | No — 20px is inherited |
| Row | row-gap: 12px | grid-template-rows: subgrid | No — 12px is inherited |
| Non-subgrid axis | — | Define own tracks | Yes — child sets its own gap |
.parent {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: auto 1fr;
column-gap: 24px;
row-gap: 16px;
}
.columns-subgrid {
grid-column: 1 / -1;
display: grid;
grid-template-columns: subgrid;
/* column-gap: 24px inherited */
row-gap: 8px; /* own row gap — allowed */
}
.rows-subgrid {
grid-row: 1 / -1;
display: grid;
grid-template-rows: subgrid;
/* row-gap: 16px inherited */
column-gap: 12px; /* own column gap — allowed */
}
Practical rule: if you set gap on a both-axis subgrid, it has no effect — both gaps come from the parent.
Nested Subgrids
Subgrid can be nested — a grandchild can subgrid into its parent, which has already subgridded into its parent. The grandchild effectively aligns to the outermost ancestor’s tracks.
.root {
display: grid;
grid-template-columns: repeat(6, 1fr);
column-gap: 16px;
}
.section {
grid-column: 1 / -1;
display: grid;
grid-template-columns: subgrid; /* inherits root's 6 columns */
}
.panel {
grid-column: span 3;
display: grid;
grid-template-columns: subgrid; /* still uses root's column tracks */
}
.panel > * {
/* Aligns to root grid column lines — two levels of nesting */
}
This enables design systems where deeply nested components can align to a global layout grid without requiring knowledge of intermediate nesting levels.
Browser Support
CSS Subgrid is supported in all modern browsers as of late 2023:
| Browser | Subgrid | Named lines | Both axes |
|---|---|---|---|
| Chrome | 117+ | 117+ | 117+ |
| Firefox | 71+ | 71+ | 71+ |
| Safari | 16+ | 16+ | 16+ |
| Edge | 117+ | 117+ | 117+ |
| Opera | 103+ | 103+ | 103+ |
Global coverage: ~85% as of early 2026. The main coverage gap is Chrome/Edge 116 and below (released before September 2023). Firefox has had subgrid since version 71 (2019), making it the pioneer.
Fallback Strategy
For browsers without subgrid support, grid items fall back to independent nested grids. Ensure layouts remain functional even without cross-item alignment:
.card {
display: grid;
/* Fallback: define own rows for older browsers */
grid-template-rows: auto 1fr auto;
}
/* Override with subgrid when supported */
@supports (grid-template-rows: subgrid) {
.card {
grid-row: span 3;
grid-template-rows: subgrid;
}
}
Common Patterns
Card Component with Aligned Sections
.card-row {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
grid-template-rows: auto 1fr auto; /* header / body / footer */
gap: 24px;
align-items: start;
}
.card {
grid-row: span 3;
display: grid;
grid-template-rows: subgrid;
background: white;
border-radius: 8px;
overflow: hidden;
}
.card-img { grid-row: 1; aspect-ratio: 16 / 9; object-fit: cover; }
.card-body { grid-row: 2; padding: 1rem; }
.card-footer { grid-row: 3; padding: 1rem; border-top: 1px solid #eee; }
Holy Grail Layout with Nested Content
.page {
display: grid;
grid-template-columns: [nav-start] 240px [main-start] 1fr [aside-start] 300px [aside-end];
grid-template-rows: auto 1fr auto;
column-gap: 24px;
}
.content-area {
grid-column: main-start / aside-start;
grid-row: 2;
display: grid;
grid-template-columns: subgrid;
/* Grandchildren align to main-start / aside-start boundary */
}
Design Token Grid
.token-grid {
display: grid;
grid-template-columns: [label-start] 180px [value-start] 1fr [type-start] 120px [type-end];
column-gap: 16px;
row-gap: 8px;
}
.token-group {
grid-column: 1 / -1;
display: grid;
grid-template-columns: subgrid;
row-gap: 4px;
}
.token-row label { grid-column: label-start / value-start; }
.token-row code { grid-column: value-start / type-start; }
.token-row span { grid-column: type-start / type-end; }
Frequently Asked Questions
What is the difference between subgrid and a regular nested grid?
A regular nested display: grid element creates entirely independent tracks — its columns and rows have no relationship to the parent grid. A subgrid element adopts the parent’s tracks directly. This means nested items can align to the parent grid’s column or row lines, which is impossible with a regular nested grid without duplicating track sizes.
Does subgrid work with implicit grid tracks?
Subgrid only inherits explicit tracks from the parent. If the parent creates implicit rows (via grid-auto-rows), those cannot be subgridded. The child must span tracks that are explicitly defined in the parent’s grid-template-columns or grid-template-rows.
Can I use subgrid on both axes at the same time?
Yes. Setting both grid-template-columns: subgrid and grid-template-rows: subgrid on the same element makes the child inherit both axes from the parent. Both column-gap and row-gap are inherited, and the child’s own gap settings on both axes are ignored.
Why does my subgrid gap still show the parent’s gap even when I set a different one?
This is expected behavior. When an axis uses subgrid, the parent’s gap for that axis is inherited and cannot be overridden. Setting column-gap on a columns-subgrid element has no effect on the inherited axis. Only the non-subgrid axis can have an independent gap.
Does subgrid work with CSS Grid’s auto keyword?
Yes. The parent can use any valid track sizing including auto, fr, minmax(), fit-content(), and repeat(). The child subgrids all inherit whatever track sizes the parent resolves to — including auto tracks that size to their content.
How do I target the second column of the parent from inside a subgrid?
Use the same grid-column placement as you would at the parent level — column numbers in a subgrid correspond to the parent’s column lines within the spanned range. For example, if the child spans columns 2–5 of the parent and uses subgrid, column line 1 inside the child maps to parent column line 2.
Related Tools
- CSS Grid Generator — Visually build CSS Grid layouts with real-time preview
- CSS @layer Reference & Generator — Configure cascade layers and visualize priority order
- CSS Container Queries Reference — Generate @container CSS for component-level responsive design
- CSS Flexbox Playground — Interactively build flexbox layouts with real-time preview