PureDevTools

CSS Subgrid Reference & Generator

Configure parent and child grid settings, generate subgrid CSS, and explore gap inheritance, named lines, and nested subgrid patterns

All processing happens in your browser. No data is sent to any server.

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

sub
sub
sub
sub
sub
sub
sub
sub
sub
sub
sub
sub

4-column parent · child spans 4 columns × 3 rows

Generated CSS

Parent grid
/* 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 subgrid
/* 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
/* 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:

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:

AxisParent gapSubgrid childCan child override?
Columncolumn-gap: 20pxgrid-template-columns: subgridNo — 20px is inherited
Rowrow-gap: 12pxgrid-template-rows: subgridNo — 12px is inherited
Non-subgrid axisDefine own tracksYes — 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:

BrowserSubgridNamed linesBoth axes
Chrome117+117+117+
Firefox71+71+71+
Safari16+16+16+
Edge117+117+117+
Opera103+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

More CSS Tools