CSS Grid Subgrid 2026
CSS Grid Subgrid 2026

CSS Grid & Subgrid 2026: Universal Support Unlocks New Patterns

Subgrid: The Missing Piece is Now Universal

CSS Grid revolutionized layout in 2017. Subgrid, which allows nested elements to participate in their parent’s grid, took years to achieve full browser support. In 2026, it’s everywhere - and it changes everything about complex layouts.

Browser Support (2026)

BrowserSupportNotes
Chrome 117+FullSince Sept 2023
Edge 117+FullChromium-based
Firefox 71+FullSince Dec 2019 (first!)
Safari 16+FullSince Sept 2022

Global support: ~95%

Subgrid is production-ready. No fallbacks needed for most audiences.

The Problem Subgrid Solves

Without Subgrid

Nested elements can’t align with the parent grid:

.card-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1rem;
}

.card {
  display: grid;
  /* This creates a NEW grid, independent of parent */
  /* Headers, content, footers won't align across cards */
}

Result: Card headers at different heights, misaligned content.

With Subgrid

.card-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: auto 1fr auto; /* Define row pattern */
  gap: 1rem;
}

.card {
  display: grid;
  grid-row: span 3; /* Span all 3 row tracks */
  grid-template-rows: subgrid; /* Inherit parent's rows */
}

Result: All card headers align, all content areas align, all footers align.

Subgrid Fundamentals

Syntax

.parent {
  display: grid;
  grid-template-columns: 1fr 2fr 1fr;
  grid-template-rows: auto 1fr auto;
}

.child {
  /* Position in parent grid */
  grid-column: 1 / -1; /* Span all columns */
  grid-row: 1 / 3; /* Span 2 rows */

  /* Become a grid that inherits tracks */
  display: grid;
  grid-template-columns: subgrid; /* Use parent's column tracks */
  grid-template-rows: subgrid; /* Use parent's row tracks */
}

One Axis Only

You can subgrid one axis while defining the other:

.child {
  display: grid;
  grid-template-columns: subgrid; /* Inherit columns */
  grid-template-rows: auto 1fr; /* Define own rows */
}

Production Patterns

Pattern 1: Aligned Card Grid

.card-container {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  /* Implicit row tracks for each card section */
}

.card {
  display: grid;
  grid-template-rows: subgrid;
  grid-row: span 4; /* header, image, content, footer */
  gap: 0;
}

.card-header { grid-row: 1; }
.card-image { grid-row: 2; }
.card-content { grid-row: 3; }
.card-footer { grid-row: 4; }
<div class="card-container">
  <article class="card">
    <header class="card-header">Short Title</header>
    <img class="card-image" src="..." alt="...">
    <div class="card-content">Content here...</div>
    <footer class="card-footer">Read more</footer>
  </article>
  <article class="card">
    <header class="card-header">Much Longer Title That Wraps</header>
    <img class="card-image" src="..." alt="...">
    <div class="card-content">More content...</div>
    <footer class="card-footer">Read more</footer>
  </article>
</div>

All headers align regardless of text length.

Pattern 2: Form Layout

.form {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 1rem 2rem;
}

.form-group {
  display: grid;
  grid-column: 1 / -1;
  grid-template-columns: subgrid;
}

.form-group label {
  grid-column: 1;
  text-align: right;
}

.form-group input {
  grid-column: 2;
}

Labels and inputs perfectly aligned without fixed widths.

Pattern 3: Product Comparison Table

.comparison {
  display: grid;
  grid-template-columns: 200px repeat(3, 1fr);
  gap: 0;
}

.comparison-row {
  display: grid;
  grid-column: 1 / -1;
  grid-template-columns: subgrid;
}

.comparison-row > * {
  padding: 1rem;
  border-bottom: 1px solid #e5e7eb;
}

.feature-name {
  grid-column: 1;
  font-weight: 600;
}

Pattern 4: Magazine Layout

.magazine-grid {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  grid-template-rows: repeat(6, minmax(100px, auto));
  gap: 1rem;
}

.feature-article {
  grid-column: 1 / 8;
  grid-row: 1 / 4;
  display: grid;
  grid-template-columns: subgrid;
  grid-template-rows: subgrid;
}

.feature-article .headline {
  grid-column: 1 / -1;
  grid-row: 1;
}

.feature-article .image {
  grid-column: 1 / 5;
  grid-row: 2 / 4;
}

.feature-article .text {
  grid-column: 5 / -1;
  grid-row: 2 / 4;
}

Subgrid with Gap Inheritance

Subgrid inherits the parent’s gap:

.parent {
  display: grid;
  gap: 2rem;
}

.child {
  display: grid;
  grid-template-columns: subgrid;
  /* Inherits 2rem gap */

  /* Override if needed */
  gap: 1rem;
}

Named Lines with Subgrid

Named grid lines work with subgrid:

.parent {
  display: grid;
  grid-template-columns:
    [sidebar-start] 200px
    [sidebar-end content-start] 1fr
    [content-end];
}

.child {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: subgrid;
}

.child-element {
  grid-column: content-start / content-end;
  /* Uses parent's named lines */
}

Combining with Container Queries

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
}

.card {
  container: card / inline-size;
  display: grid;
  grid-row: span 3;
  grid-template-rows: subgrid;
}

@container card (width < 350px) {
  .card-content {
    /* Adjust content for narrow cards */
    font-size: 0.9rem;
  }
}

Common Mistakes

Mistake 1: Forgetting to Span

/* ❌ Child doesn't span enough tracks */
.child {
  /* Implicitly grid-row: span 1 */
  grid-template-rows: subgrid; /* Only gets 1 row */
}

/* âś… Span the tracks you need */
.child {
  grid-row: span 3;
  grid-template-rows: subgrid; /* Gets 3 rows */
}

Mistake 2: Mixing Subgrid with Explicit Tracks

/* ❌ Can't mix subgrid with explicit sizes */
.child {
  grid-template-columns: subgrid 100px 1fr; /* Invalid */
}

/* âś… All or nothing per axis */
.child {
  grid-template-columns: subgrid;
  /* OR */
  grid-template-columns: 100px 1fr;
}

Performance Notes

Subgrid is well-optimized in modern browsers:

  1. Single layout pass - Parent and children calculate together
  2. No JavaScript needed - Pure CSS alignment
  3. Minimal reflow - Changes contained within grid context

Key Takeaways

  1. Universal support - Subgrid works in all major browsers (95%+)
  2. Alignment solved - Nested elements align with parent grid tracks
  3. One or both axes - Apply subgrid to columns, rows, or both
  4. Gap inheritance - Subgrid inherits parent’s gap (overridable)
  5. Named lines work - Parent’s line names available in subgrid

Subgrid completes CSS Grid. Layouts that previously required JavaScript or hacky CSS are now trivial. If you’re building cards, forms, or any component with parts that need to align across instances, subgrid is the answer.

Link copied!

Comments for cssgrd