🚀 LEVEL UP TO SENIOR:Unlock 500+ Advanced Practical Challenges & Exercises.
🎓 COURSERA PARTNER:Earn professional Google, Meta, and IBM certificates to supercharge your resume.
CSS MASTER CLASS /// VISUAL ENGINEERING /// LAYOUT DESIGN /// ANIMATION LAB /// CSS MASTER CLASS /// VISUAL ENGINEERING ///

Subgrid: Aligning Nested Grids To Their Parent

Understand why nested grids don't align by default, how subgrid lets a nested grid adopt its parent's exact track sizing, and how named grid lines propagate automatically through subgrid for self-documenting layouts.

Total XP: 0|💻 css XP: 0

Skill Matrix

UNLOCK NODES BY LEARNING NEW TAGS.

Subgrid

Aligning nested grids to their parent.


🚀 LEVEL UP TO SENIOR:Unlock 500+ Advanced Practical Challenges & Exercises.
🎓 COURSERA PARTNER:Earn professional Google, Meta, and IBM certificates to supercharge your resume.

CSS Grid solved most layout problems on its own, but one stubborn case remained: aligning content inside independently-sized nested grids, like a row of cards with varying content. Subgrid closes that gap.

1The Classic Card-Row Alignment Problem

Picture a row of pricing cards, each with a title, a variable-length description, and a footer button. If each card independently uses display: grid to lay out its own title/body/footer, every card's internal rows size purely based on that card's own content — a card with a longer title pushes its body down, while its neighbor's shorter title doesn't, breaking the visual alignment of the whole row.

Before subgrid, fixing this required either JavaScript measuring the tallest title across all cards and forcing a fixed height, or abandoning per-card grids in favor of one giant, harder-to-reason-about parent grid spanning every card's internals directly.

/* Each .card's rows size independently of its siblings */
.card { display: grid; grid-template-rows: auto 1fr auto; }
localhost:3000
⚠ Misaligned RowsCard titles, bodies, and footers don't line up across a row of independently-sized nested grids.

2How subgrid Solves It Directly

The parent grid defines the shared row tracks once — title row, body row, footer row — sized to fit the tallest content across all cards. Each card, instead of declaring its own independent grid-template-rows, sets grid-template-rows: subgrid and spans the appropriate number of parent rows with grid-row: span 3. The card's own children (title, body, footer) then align to those exact same parent-defined row lines as every sibling card's children.

The result: every card's title sits on the same line, every footer sits on the same line, regardless of how much content any individual card actually has — solved entirely in CSS, with zero JavaScript measurement.

.card-grid { display: grid; grid-template-rows: auto 1fr auto; }
.card { grid-row: span 3; grid-template-rows: subgrid; }
localhost:3000
✓ Perfectly AlignedEvery card's title, body, and footer now line up across the row, because each card's internal rows are the parent's actual tracks.

3Named Lines Keep Deeply Nested Layouts Self-Documenting

When the parent grid names its tracks — [title-start] auto [body-start] 1fr [footer-start] auto [footer-end] — a subgrid automatically inherits those same named lines. A card's title element can then be placed with grid-row: title-start, using the exact same semantic vocabulary the parent grid defined, rather than reasoning about raw numeric line indices that shift if the grid structure changes.

This compounds well with larger design systems: a page-level layout grid can define named regions once, and every nested subgrid throughout the component tree can reference those same names consistently, keeping alignment intent readable even several nesting levels deep.

.card-grid {
  grid-template-rows: [title-start] auto [body-start] 1fr [footer-start] auto;
}
.card__title { grid-row: title-start; }
localhost:3000
Named lines: title-start, body-start, footer-start
Inherited automatically by every subgrid

4Step-by-Step Breakdown

When A Nested Grid Needs To Line Up With Its Parent. Put a grid inside a grid item, and by default it creates its own independent set of tracks — completely unaware of the parent grid's column and row lines. subgrid changes that: a nested grid can adopt its parent's tracks directly, so content inside sibling cards finally aligns even when each card's internal content varies in length.

The Problem: Independent Nested Grids Don't Align. A row of cards, each internally using display: grid for its title/body/footer, will not align those internal rows across cards by default — one card's grid is entirely independent of its neighbor's, even though visually they're supposed to line up in a shared row.

The Misalignment Problem. Why don't three cards, each with display: grid and varying content, align their internal rows by default?

  • It's a browser rendering bug
  • Each nested grid establishes its own independent set of tracks, unaware of its siblings or parent
  • Grid can never align nested content; only Flexbox can

Adopting Parent Tracks With subgrid. Setting grid-template-columns: subgrid (or -rows) on a nested grid item tells it to adopt its parent's track definitions directly for that axis, instead of defining its own. The nested grid's own children then align to the exact same lines as their cousins in sibling cards.

Using subgrid. What does grid-template-rows: subgrid do on a nested grid item?

  • It creates a brand new, independent set of row tracks
  • It makes the nested grid adopt the row tracks of its parent grid directly
  • It disables grid layout on that element entirely

Named Lines Propagate Through Subgrid. A particularly powerful detail: named grid lines defined on the parent grid are inherited by a subgrid automatically, letting nested content reference the same semantic line names ([title-start], [footer-end]) as the outer grid, keeping the whole layout's structure self-documenting across nesting levels.

Named Line Inheritance. If a parent grid defines a named line like [title-start], can a subgrid's children reference that same name directly?

  • No — named lines must be redeclared inside the subgrid
  • Yes — subgrid inherits the parent's named lines automatically
  • Only if the subgrid explicitly renames them first

Subgrid Alignment Mastered. You now understand why nested grids misalign by default, how subgrid lets a nested grid adopt its parent's exact tracks, and how named grid lines propagate through subgrid to keep deeply nested layouts semantically consistent.

Inherit The Parent Grid's Tracks. grid-template-columns: subgrid lets a nested grid align to its parent grid's column tracks exactly.

Level Up 🚀

Advanced cheat sheets, SEO tricks, and interview prep for this topic.

Browser Support

ChromeSupported

Fully supported.

FirefoxSupported

Fully supported.

SafariSupported

Fully supported.

EdgeSupported

Fully supported.

Accessibility (A11y)

1Subgrid Should Not Change The Underlying DOM Or Reading Order

Subgrid only affects visual track alignment; the actual source order of cards and their content should still make logical sense when read linearly, since that source order is what determines screen reader and keyboard tab sequence.

2Consistent Visual Alignment Achieved Via Subgrid Can Improve Scannability For Low-Vision Users

Reliably aligned titles, bodies, and footers across a row of cards make the page easier to visually scan for users with low vision or cognitive load concerns, compared to a visually jagged, misaligned card row.

SEO Implications

  • 1

    Subgrid Eliminates JavaScript Height-Matching Previously Used For Card Alignment

    Removing a JS-based 'measure the tallest card and force equal heights' script reduces main-thread work and layout thrashing, both of which factor into Core Web Vitals metrics.

  • 2

    CSS-Only Alignment Avoids Content Reflow Caused By Post-Load JavaScript Measurement

    JS-based height-matching typically runs after initial render, causing a visible reflow; subgrid achieves the same alignment in the initial layout pass, avoiding that visual shift entirely.

Best Practices

Reach For Subgrid Before Reaching For A JavaScript Height-Matching Library

It solves the exact same problem natively, with better performance and no post-load reflow, for any browser supporting CSS Grid Level 2.

Name Your Parent Grid's Tracks When Using Subgrid Across Multiple Nesting Levels

Named lines propagate automatically and keep deeply nested layout code readable, instead of forcing every nested component to reason about raw numeric line positions.

Frequent Bugs

THE BUG

A subgrid item's content doesn't align with its siblings despite using grid-template-rows: subgrid.

THE FIX

Confirm the item also has the correct grid-row (or grid-column) span matching the number of parent tracks it should adopt — subgrid alone without the right span doesn't establish the relationship.

THE BUG

Rows in a subgridded card don't seem to inherit the expected sizing from the parent.

THE FIX

Double check the axis: subgrid must be declared on the same axis (rows vs columns) you're trying to inherit — declaring grid-template-columns: subgrid does nothing for row alignment.

Real-World Examples

A Pricing Card Row With Aligned Internals

Three pricing cards with varying description lengths, using subgrid so every card's title, price, feature list, and CTA button align perfectly across the row.

.pricing-grid { display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: auto auto 1fr auto; }
.pricing-card { grid-row: span 4; display: grid; grid-template-rows: subgrid; }

Interview Prep

?Frequently Asked Questions

Pascual Vila

Pascual Vila

Frontend Instructor // Code Syllabus

Common Pitfalls & Errors

The Error //

Using subgrid without a matching grid-row or grid-column span

/* Wrong: no span declared */ .card { grid-template-rows: subgrid; } /* Correct */ .card { grid-row: span 3; grid-template-rows: subgrid; }

The Solution //

Subgrid needs an explicit span matching the number of parent tracks it should adopt to establish the relationship correctly.

The Error //

Declaring subgrid on the wrong axis for the alignment problem being solved

/* For row alignment */ .card { grid-template-rows: subgrid; }

The Solution //

Use grid-template-rows: subgrid for row alignment and grid-template-columns: subgrid for column alignment — they're independent.

Lesson Glossary

[01]Subgrid

A value making a nested grid adopt its parent grid's tracks.

Code Preview
grid-template-rows: subgrid

[02]Track

A single row or column in a CSS Grid layout.

Code Preview
1fr, auto

[03]Named Grid Line

A custom name assigned to a grid line for semantic placement.

Code Preview
[title-start]

[04]Nested Grid

A grid container placed inside another grid's item.

Code Preview
.card { display: grid; }

Continue Learning