Creating complex layouts with CSS Grid is awesome, but aligning nested elements—like items inside a grid cell—can get tricky. That’s where CSS Subgrid comes in. It lets child elements inherit the grid lines of their parent, making it easier to keep everything aligned. Let’s explore how Subgrid works and build a practical example to see it in action.
What is CSS Subgrid?
CSS Subgrid is an extension of CSS Grid. It allows a nested grid (inside a grid item) to use the same grid lines as its parent grid. This means you don’t have to redefine column or row sizes for child elements—they just follow the parent’s structure. It’s perfect for things like card layouts, product listings, or dashboards where nested content needs to stay perfectly aligned.
Why Use Subgrid?
- Consistency: Child elements align perfectly with the parent grid, no matter how complex the layout.
Less Code: You don’t need extra CSS or media queries to match sizes.
- Responsive: Subgrid adapts to the parent grid’s responsive settings automatically.
A Simple Example: Product Listing
Let’s create a product listing with cards that have aligned titles, prices, and buttons, even though each card has nested content. We’ll use Subgrid to keep everything neat.
HTML Structure
We’ll have a parent grid for the product cards, and each card will have its own grid for internal content (like title, price, and button).
<div class="grid-container"> <div class="card"> <h2>Product One</h2> <p class="price">$29.99</p> <button>Add to Cart</button> </div> <div class="card"> <h2>Product Two</h2> <p class="price">$49.99</p> <button>Add to Cart</button> </div> <div class="card"> <h2>Product Three</h2> <p class="price">$19.99</p> <button>Add to Cart</button> </div> </div>
CSS with Subgrid
Here’s how we set up the parent grid and use Subgrid for the cards.
/* Parent grid */ .grid-container { display: grid; grid-template-columns: repeat(3, 1fr); /* 3 equal columns */ gap: 20px; padding: 20px; max-width: 1200px; margin: 0 auto; } /* Each card is a grid item with its own grid */ .card { display: grid; grid-template-rows: auto auto 1fr; /* Rows for title, price, button */ gap: 10px; padding: 15px; border: 1px solid #ddd; border-radius: 8px; /* Inherit the parent's column structure */ grid-template-columns: subgrid; grid-column: span 1; /* Each card takes one column of the parent */ } /* Style the card content */ .card h2 { font-size: 1.5rem; margin: 0; } .card .price { font-size: 1.2rem; color: #2ecc71; } .card button { padding: 10px; background: #3498db; color: white; border: none; border-radius: 4px; cursor: pointer; } .card button:hover { background: #2980b9; }
What’s Happening Here?
Parent Grid: The .grid-container sets up a 3-column grid with grid-template-columns: repeat(3, 1fr).
Subgrid: Each .card uses display: grid and grid-template-columns: subgrid, so it inherits the parent’s column structure. This ensures all cards align perfectly with the parent grid’s columns.
Rows in Cards: We define rows with grid-template-rows: auto auto 1fr to organize the title, price, and button vertically.
Responsive: Since the cards inherit the parent’s columns, they’ll adjust automatically if the parent grid changes (e.g., with media queries).
Output
Making It Responsive
Let’s add a media query to make the layout stack on smaller screens.
@media (max-width: 768px) { .grid-container { grid-template-columns: 1fr; /* Stack cards in one column */ } }
With Subgrid, the cards will still align perfectly because they inherit the parent’s single-column layout. No need to tweak the card’s internal grid!
Benefits of This Approach
Alignment: The title, price, and button in each card line up across all cards, even if their content varies in length.
Simplicity: No need to manually set column widths or use extra divs to force alignment.
Flexibility: You can easily change the parent grid (e.g., from 3 columns to 2 or 1), and the cards adapt without extra CSS.
Browser Support
Subgrid is supported in all modern browsers (Chrome, Firefox, Safari, Edge) as of 2025. For older browsers, you can use a fallback like regular CSS Grid or Flexbox. For example:
/* Fallback for browsers without Subgrid */ @supports not (grid-template-columns: subgrid) { .card { grid-template-columns: 1fr; /* Simple single-column fallback */ } }
Try It Out!
Subgrid is a game-changer for layouts with nested content. Try tweaking the example above—maybe add more columns, adjust the gaps, or style the cards differently. You can also experiment with Subgrid for rows by using grid-template-rows: subgrid if your parent grid defines rows.
Top comments (0)