New: We've launched a brand new Coding Challenges section! Check out these interactive, real-world exercises to level up your skills.Explore Challenges
FrontendPrep
cssMedium

CSS Grid Subgrid: What is it and how do you use it?

Loading...

Learn how the CSS Grid subgrid feature allows grid items to inherit and align with their parent grid tracks, solving complex card layout alignment challenges.

Arvind M
Arvind MLinkedIn

CSS Grid Subgrid: Alignment Across Card Components

A common challenge in frontend layouts is aligning internal elements of separate card components. For example, if you have a row of card elements with dynamic content, you want their headers, images, bodies, and footers to align horizontally across cards, regardless of content size differences.

Historically, this required rigid heights or complex JavaScript solutions. Modern CSS introduces Subgrid to solve this exact issue.


The Core Problem: Dynamic Card Row Alignment

Consider a standard three-column card row. Each card contains a title, a brief description, and a footer button:

<div class="grid-container">
  <div class="card">
    <h3>Short Title</h3>
    <p>Brief text description.</p>
    <button>Footer Button</button>
  </div>
  <div class="card">
    <h3>A Much Longer Title That Wraps to Two Lines</h3>
    <p>A longer text description that occupies more space vertically.</p>
    <button>Footer Button</button>
  </div>
  <div class="card">
    <h3>Title</h3>
    <p>Short desc.</p>
    <button>Footer Button</button>
  </div>
</div>

If we make the .grid-container a grid, the cards themselves align perfectly. However, the internal headers, paragraph text, and buttons do not. If Card 2's header wraps to two lines, Card 1's description will still start higher, breaking horizontal reading alignment across the cards.


The Solution: CSS Grid Subgrid

Subgrid allows child elements of a grid item (grand-children of the parent grid container) to opt-in to the parent grid's column or row tracks.

Here is the modern CSS way to solve this:

/* Parent Grid Container */
.grid-container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
}
 
/* Card item (child of grid-container, parent of internal elements) */
.card {
  display: grid;
  /* Occupy three rows in the parent grid layout */
  grid-row: span 3;
  
  /* Opt-in to inherit the row definitions of the parent grid */
  grid-template-rows: subgrid;
  gap: 10px;
}

How it works:

  1. The parent .grid-container defines columns, but leaves rows to grow implicitly.
  2. The card element spans 3 rows (grid-row: span 3) within the parent container.
  3. The card sets grid-template-rows: subgrid. Instead of defining its own row heights, it hands control over to the parent grid container.
  4. The browser aggregates the heights of headers, descriptions, and buttons across all cards in the row. It aligns them perfectly:
    • Row 1 across all cards gets the height of the tallest header.
    • Row 2 gets the height of the tallest description.
    • Row 3 gets the height of the tallest button.

Specifying Subgrid for Columns

Subgrid works just as well for columns. If you want child elements of a component to align perfectly with the parent column structure, specify subgrid on columns:

.sidebar-wrapper {
  display: grid;
  grid-column: span 2;
  /* Inherit columns from the parent layout grid */
  grid-template-columns: subgrid;
}

Browser Support and Fallbacks

CSS Subgrid is now widely supported in all modern greenfield browsers (Chrome, Safari, Firefox, Edge).

To ensure layouts remain usable on legacy browsers, use a feature query to wrap subgrid styles:

.card {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}
 
@supports (grid-template-rows: subgrid) {
  .grid-container {
    /* Define row tracks for child contents */
    grid-auto-rows: auto auto auto;
  }
  
  .card {
    display: grid;
    grid-row: span 3;
    grid-template-rows: subgrid;
  }
}

Key Takeaways for Interviews

  • What is Subgrid?: It is a value for grid-template-rows or grid-template-columns that allows a nested grid container to use the track lines defined on its parent grid container.
  • Why use it?: It aligns grandchild elements across different grid cells (like card contents in a multi-card row) without manual/hardcoded heights or JavaScript.
  • Syntax: Set grid-row: span N or grid-column: span N to declare how many tracks the subgrid spans, then specify grid-template-rows: subgrid or grid-template-columns: subgrid on the child container.

Finished practicing this challenge?

Mark it as completed to track your progress, or bookmark it to review later.

Loading...

Share this Resource

Help other developers level up by sharing this study guide.

⚡ Weekly newsletter

Crack Your Next Frontend Interview.

Join senior engineers who receive practical, deep-dive frontend challenges, detailed concepts, and blueprints directly in their inbox.

  • Senior level React, JS, and CSS interview blueprints
  • System Design & performance optimization deep-dives
  • 100% free, zero spam, unsubscribe with one click

Join the Study Track

We value your privacy. Unsubscribe at any time.

More Technical Questions

Expand your mastery. Deep dive into other frontend interview challenges in this category.