Design Perfectly Aligned Layouts with CSS Subgrid

CSS Grid Layout is a two-dimensional grid-based layout system for websites. It makes it easy to arrange content in rows and columns and create responsive layouts.

If you're familiar with grid layouts, you've probably encountered the following issue: A grid container can be placed inside another grid to create a nested grid layout. Unfortunately, the content of the child grid doesn't automatically align with the parent grid. But don't worry! We can solve this issue with the subgrid feature!

A chessboard with a grid of rows and columns. Photo: © RODNAE Productions / pexels.com

The subgrid feature makes grid layout even more powerful and enables us to create perfectly aligned layouts. I've prepared a demo of a typical use case. Let's see how it all works.

The Basics of Grid Layout

The grid layout system is defined in the CSS Grid Layout Module specification:

A two-dimensional grid-based layout system, optimized for user interface design. In the grid layout model, the children of a grid container can be positioned into arbitrary slots in a predefined flexible or fixed-size layout grid.

You can turn an HTML element into a grid container with the CSS property display: grid. Next, you can define the rows and columns with the properties grid-template-rows and grid-template-columns.

There are many ways to define a grid and populate it with content. Listing all possible settings and scenarios would go beyond the scope of this article. If you want to learn more, I can recommend the tutorials “A Complete Guide to CSS Grid” and “Learn CSS Grid”.

What is Subgrid and What's it Good for?

The subgrid feature was added in CSS Grid Layout Module Level 2. The specification states:

A nested grid can defer the definition of its rows and/or columns to its parent grid container, making it a subgrid. In this case, the grid items of the subgrid participate in sizing the parent grid, allowing the contents of both grids to align.

To define a subgrid, you simply set the value subgrid for the property grid-template-rows or grid-template-columns. That's it! The nested grid will now use the columns and/or rows defined by the parent grid and align its content accordingly.

Demo: Punk API Beer List

I've created a React demo that displays a list of beers in a grid with three equally sized columns. Each grid cell contains information about a specific beer. Check out the live version here (best viewed on a desktop screen).

The Parent Grid Container

The demo uses an unordered list as the parent grid container. Here's the JSX code:

<ul className={styles.beerGrid}> {items.map(item => ( <li key={item.id}> <BeerItemDetails item={item} /> </li> ))} </ul>

In my CSS code, I use the repeat and minmax functions to create a grid with three columns and a variable number of rows. Each column is equally sized with a minimum width of 15rem.

ul.beerGrid { display: grid; gap: 2.5rem; grid-template-columns: repeat(3, minmax(15rem, 1fr)); grid-template-rows: auto; list-style: none; }

Turning the Beer Content Cards into Subgrids

Each list item is rendered using the BeerItemDetails React component. This component consists of a header section (hgroup element) and a details section (div element):

<hgroup className={styles.heading}> <h2>{item.name}</h2> <p>{item.tagline}</p> </hgroup> <div className={styles.flexRow}> <!-- details --> </div>

In my CSS code, I define the list items as grid containers with two rows (grid-row: span 2). The grid-template-rows: subgrid declaration tells the browser to align the header and details section of each beer card that is placed on the same row.

ul.beerGrid li { display: grid; grid-template-rows: subgrid; grid-row: span 2; gap: 0; }

Easier Development with CSS Grid Inspector

I made heavy use of the CSS Grid Inspector that is part of Firefox DevTools. This awesome tool highlights your grid's rows and columns and makes it easier to understand how the parent grid and its subgrids fit together.

The Chrome DevTools offer a similar tool. But as a passionate Firefox user, I just had to mention the Firefox tool first. 😉

Browser Support and Progressive Enhancement

At the time of publication of this post, only Safari and Firefox support the subgrid feature. But don't worry! You don't have to wait for Chrome and Edge to catch up.

Apply the principle of progressive enhancement to provide a basic layout and also take advantage of the subgrid feature in supporting browsers. To achieve this, we use @supports to check browser support before we set the subgrid value:

@supports (grid-template-rows: subgrid) { ul.beerGrid li { display: grid; grid-template-rows: subgrid; } }

Useful Resources

Posted on