CSS Grid Subgrid: The Feature That Changes How You Build Layouts

By Eoin Villarin, 2025-10-15, updated 2026-10-28

CSS subgrid lets nested elements line up with their parent grid, so card buttons, form labels and pricing rows finally align. Learn how it works, real patterns and 2026 browser support.

What is CSS subgrid and how do I use it to align card layouts?

CSS subgrid lets a nested grid adopt its parent's tracks instead of creating its own, so titles, descriptions and buttons line up across sibling cards. Give each card display: grid, grid-row: span 3 and grid-template-rows: subgrid so it spans and shares three parent rows. It became Baseline Widely available on 15 March 2026.

Key takeaways

  • CSS subgrid shipped in Firefox 71 in 2019, Safari 16, and Chrome and Edge 117 in September 2023.
  • Inside a subgrid, line numbers restart at 1, but named lines from the parent grid are inherited.
  • A subgridded axis cannot create implicit tracks, so extra items go into the last track instead.
  • For older browsers, start with a flexbox card layout and upgrade it inside an @supports (grid-template-rows: subgrid) query.
  • Tailwind CSS includes grid-cols-subgrid and grid-rows-subgrid utilities that output the standard subgrid value.

CSS subgrid fixes one of the oldest annoyances in web layout: content inside nested elements that refuses to line up. You build a tidy row of cards, and the titles wrap to different lengths, the descriptions push the buttons down unevenly, and the whole grid looks slightly broken even though every card is technically correct.

For years the workarounds were JavaScript height matching, fixed heights that break with real content, or flexbox tricks that only align the last item. Subgrid solves the problem in CSS with a single value, and as of March 2026 it is officially Baseline Widely available across all major browsers.

In this guide you will learn what subgrid does, the syntax and rules that trip people up, three production patterns for cards, forms and pricing tables, how it compares with flexbox and container queries, and how to ship a fallback if you still support older browsers.

What problem does CSS subgrid solve?

When you set display: grid on a container, only its direct children become grid items. If one of those children is also a grid, it creates a completely independent set of tracks. Its rows know nothing about the rows in the card next to it.

Jumble of wooden letter blocks in uneven sizes, like cards that size rows on their own
Without subgrid, each card sizes its rows on its own. Photo: rawpixel, CC0

That is fine for many layouts, but it breaks any design where inner content should align across siblings. Card titles, prices, feature lists and call-to-action buttons each size themselves inside their own card, so a long title in one card shifts everything below it while the neighbouring cards stay put.

Subgrid lets a nested grid adopt the tracks of its parent instead of creating new ones. Every card shares the same row tracks, so the tallest title in a row decides the height of the title row for every card in that row.

How CSS subgrid works: syntax and core rules

You activate subgrid on an element that is both a grid item and a grid container, by using subgrid as the value of grid-template-columns, grid-template-rows or both:

.parent {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
}

.child {
  grid-column: 2 / 6;              /* spans four parent columns */
  display: grid;
  grid-template-columns: subgrid;  /* children use those four tracks */
}

The .child now has four column tracks that are exactly the same size as the parent tracks it spans. Its own children can be placed on them as if they were direct children of .parent.

Rows, columns or both

You can subgrid one axis and define the other normally. Card layouts usually subgrid rows, forms usually subgrid columns, and full page layouts sometimes subgrid both. On an axis you do not subgrid, the element behaves like any other nested grid.

The rules that trip people up

  • Line numbers restart. Inside the subgrid, line 1 is the subgrid's first line, not the parent's. That makes components portable wherever you place them.
  • Line names are inherited. Named lines from the parent are available inside the subgrid, and you can add your own with subgrid [a] [b].
  • Gaps are inherited but can be overridden. Set row-gap or column-gap on the subgrid to change the spacing between its own tracks.
  • No implicit tracks in a subgridded axis. If you place more items than there are tracks, the extras are put into the last track instead of creating new rows. Make the span match your content.
  • Content still influences sizing. With auto tracks, content inside the subgrid can grow the parent track, which is exactly what makes alignment work.

The MDN subgrid guide has interactive examples of each rule, and the behaviour is defined in the CSS Grid Layout Module Level 2 specification.

Pattern 1: card grid with aligned titles, text and buttons

This is the use case that makes subgrid click for most designers. Each card has three parts: a title, a description and an action. We want every part to line up across a row of cards, whatever the content length.

Grid notebook with glasses and pencils, its shared lines keeping every row aligned
Shared row tracks keep every card part aligned. Photo: rawpixel, CC0
<ul class="cards">
  <li class="card">
    <h3>Starter website</h3>
    <p>Five pages, a contact form and on-page SEO set up properly.</p>
    <button type="button">Get a quote</button>
  </li>
  <li class="card">...</li>
  <li class="card">...</li>
</ul>
.cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
  gap: 2rem 1.5rem;
}

.card {
  display: grid;
  grid-row: span 3;               /* title, body, action */
  grid-template-rows: subgrid;
  row-gap: 0.75rem;               /* tighter spacing inside each card */
  padding: 1.5rem;
}

.card > button {
  justify-self: start;
  align-self: end;
}

Each card spans three implicit rows on the parent grid and hands them to its children. The parent's 2rem row gap separates one row of cards from the next, while the card's own row-gap keeps its internal spacing tight.

Because the grid uses auto-fill, the layout stays responsive. On a phone each card sits in its own row, and on wider screens the cards in each row align automatically. This is the layout I reach for on service grids, blog listings and ecommerce collection pages, where uneven product titles are the norm.

Pattern 2: forms with aligned labels and inputs

Forms are the second classic case. You want every label in one column sized to the longest label, and every input in a second column, but each label and input pair should stay wrapped together for semantics and styling.

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

.field {
  display: grid;
  grid-column: 1 / -1;
  grid-template-columns: subgrid;
  align-items: center;
}

@media (width < 40rem) {
  .form { grid-template-columns: 1fr; }
}

Each .field spans both parent columns and passes them to its label and input. The label column grows to fit the longest label in the whole form, not just in one field. On small screens the parent collapses to a single column, and the fields follow.

Pattern 3: pricing tables and full-bleed page sections

Pricing tables are card grids with more rows. If each plan has a name, a price, a short summary, four feature lines and a button, give each plan grid-row: span 8 and grid-template-rows: subgrid, and every feature lines up across plans so visitors can compare at a glance.

Subgrid also simplifies page layouts that mix contained and full-width sections. Define named lines on the page grid once, then let each section inherit them:

.page {
  display: grid;
  grid-template-columns:
    [full-start] minmax(1rem, 1fr)
    [content-start] minmax(0, 72rem) [content-end]
    minmax(1rem, 1fr) [full-end];
}

.section {
  grid-column: full;
  display: grid;
  grid-template-columns: subgrid;
}

.section > * { grid-column: content; }
.section > .bleed { grid-column: full; }

Every section background can stretch edge to edge while its text stays inside the content column, with no wrapper divs or negative margins.

Subgrid vs flexbox vs container queries: which tool when?

Subgrid does not replace the other layout tools. It solves a specific alignment problem. Here is how I decide:

GoalBest toolWhy
Align inner parts across sibling cardsSubgridSiblings share the same row tracks
Push one button to the bottom of each cardFlexbox with margin-top: autoSimple, but only aligns the last item
Change a component layout based on its own widthContainer queriesResponds to the container, not the viewport
One-dimensional rows of tags or buttonsFlexboxWrapping content of unknown size
Page sections with contained and full-bleed contentSubgrid with named linesOne set of lines shared by every section

They also combine well. A card can be a subgrid for alignment and a size container for its internal layout. If you use Tailwind, the grid-rows-subgrid and grid-cols-subgrid utilities map directly to these values, and my Tailwind CSS v4 guide covers the container query utilities that pair with them.

CSS subgrid browser support in 2026

Firefox shipped subgrid first in version 71 in 2019, Safari followed in version 16, and Chrome and Edge added it in version 117 in September 2023. That made it Baseline Newly available on 15 September 2023. Under the Baseline definition, a feature becomes Widely available 30 months later, and subgrid reached that status on 15 March 2026.

Laptop and smartphone on a dark wooden floor, ready for testing a layout on real devices
Test the layout and its fallback on real devices. Photo: rawpixel, CC0
Baseline Widely available means you no longer need a reason to use subgrid. You need a reason not to, such as a known audience on very old browsers.

If your analytics show meaningful traffic from older browsers, for example embedded webviews or locked-down corporate machines, start with a flexbox layout and upgrade it with a feature query:

.card {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}
.card > button { margin-top: auto; }

@supports (grid-template-rows: subgrid) {
  .card {
    display: grid;
    grid-row: span 3;
    grid-template-rows: subgrid;
  }
  .card > button { margin-top: 0; }
}

Older browsers get cards with bottom-aligned buttons, and modern browsers get full alignment. Nobody gets a broken layout.

How to debug subgrid in browser DevTools

Firefox, Chrome and Safari all include grid inspectors that overlay track lines, numbers and names on the page. When a subgrid layout looks wrong, turn on the overlay for both the parent and the subgridded child. The usual culprits are a span that does not match the number of children, a forgotten display: grid on the child, or padding on the subgrid that offsets its content from the parent lines.

Modern CSS keeps removing the need for layout JavaScript. If you liked this, my guide to view transitions, anchor positioning and scroll-driven animations covers the next set of features worth adopting, and my design system guide shows how to package patterns like these as reusable components.

Frequently asked questions

Is CSS subgrid safe to use in production?

Yes. Subgrid has been supported in Firefox since version 71, Safari since 16 and Chrome and Edge since 117, and it became Baseline Widely available in March 2026. For most public websites you can use it without a fallback. If you support very old browsers or embedded webviews, wrap it in an @supports query with a flexbox fallback.

What is the difference between a nested grid and a subgrid?

A nested grid defines its own independent tracks, so its rows and columns ignore everything outside it. A subgrid reuses the tracks its parent already defined for the area it spans. That shared sizing is what lets content in separate cards or form fields align with each other, while line numbering still restarts inside the subgrid.

Can I use subgrid for rows and columns at the same time?

Yes. Set both grid-template-columns and grid-template-rows to subgrid and the element uses the parent's tracks in both directions. Be careful with automatic placement, because a subgridded axis cannot create implicit tracks. Extra items are placed in the last track, so the number of spanned tracks must match the content.

Does subgrid work with Tailwind CSS?

Yes. Tailwind includes grid-cols-subgrid and grid-rows-subgrid utilities. Combine them with span utilities such as row-span-3 on the card and a grid on the parent, and you get the aligned card pattern from this guide without writing custom CSS. The same browser support rules apply, because Tailwind outputs the standard subgrid value.

Next steps: put subgrid to work

Pick one layout on your site where alignment has always bothered you, usually a card grid or pricing table, and rebuild it with subgrid. Delete any JavaScript height matching, test it at every breakpoint and keep a feature query fallback only if your analytics justify it.

If you want a site with layouts that hold up on every screen, tell me about your project through my contact form, or browse my web design and development case studies to see recent builds.

Related reading