Let's create a layout using subgrid. Still rather new at the time of writing this article and not yet supported in all major browsers, one of the new features currently being implemented with in the CSS Grid Layout Module is subgrid. Figure 1 shows the current browser support for subgrid.
But first, what functionality does subgrid bring that was not previously available in grid? What subgrid does is allow child elements to be able to use the tracks created on their parent elements. In other words, child elements operate on their parent's rows and columns allowing us to align our elements much more neatly. Let's look at how this works in practice.
We are going to use subgrid to layout a list of 4 projects found in a list that each have an image, name, description, and link in a 4 column layout. Our HTML looks as follows (listing 1):
And our webpage looks as seen in figure 2.
We start by giving our list a
display property value of
grid and defining 4 columns (one for each project). Since we want all 4 columns to be the same width we use
repeat(), which allows us to define the number of columns to create for a specified dimension. We also remove the list style and default padding from the list. Our CSS therefore looks as follows (Listing 2).
Now that we have our columns (figure 3) we can start focusing on the individual elements found within each project (image, name, description, and list).
Notice that the project names and description sections are not all the same length. (Yes the extra characters at the end of the second project - Cirrostyle - are not an oversight, they are there to make the title wrap). What we want to do is have each type of content neatly aligned horizontally. We will use
subgrid to achieve this.
subgrid property value gets assigned to either
grid-template-rows, or both. In our case, since we are looking for horizontal alignment, we will use it on
grid-template-rows. Notice that we still need to give the project (
<li>) a display value of
grid (listing 3).
At this after applying this property, we will not notice all of our content is now found in the first row as seen in figure 3.
Let's go ahead and define our rows. This will be done on the parent (the
<ul>). We are going to give each row the following values:
- First row (image):
- Second row (project name):
- Third row (description):
- Fourth row (link):
Our updated list CSS will therefore look as follows (listing 4):
Although we defined our rows, we can see that our content is still found in the first row (figure 5). The row is now smaller, but the project's individual elements have not been distributed across the newly created rows.
Even if we explicitly assign rows to each individual project element (listing 5) we find that our content stays stubbornly stuck in that first row (figure 6).
The reason the project content elements are sticking to that first row is because we have not assigned a row value to the project itself (
<li>). Unless otherwise defined, by default elements will take up 1 cell's worth of space (both horizontally and vertically). We need our
<li> element to span 4 rows. This will render the rows available to the subgrid and the project content will be able to align itself correctly. Once we update our
<li>'s (listing 5) we see that our project elements fall into place (figure 7).
With our content in the correct rows, let's do a little bit of clean up. Our images extend past the width of the columns and are causing some overflow. To fix that, we will give our images a
We are also going to add some space between our columns using the
gap property. Although we want to add space between the columns, we don't want to add any between the rows. We therefore assign 2 values to our declaration. A first one of
row-gap) and a second of
column-gap). Listing 7 shows our updated CSS and figure 8 our progress thus far. Notice that the
gap declaration is added to the list, not the individual projects.
Let's put some finishing touches on our layout. We are going to center the images horizontally in the middle of their columns and center the project names vertically in the middle of their rows. Let's start with the images. To center the images horizontally we will use
justify-self with a value of
center. To center to project names vertically, we use
align-self also with a value of
center as seen in listing 8.
With these final adjustments, our layout looks pretty good (figure 9) but let's take a look at what we look like in Chrome (figure 10). Spoiler, at the time or writing this article, Chrome does not support subgrid yet.
Creating a fallback
Although our layout doesn't look awful in Chrome, let's go ahead and make it a little better by adding a fallback. We are going to use the
@supports at-rule to provide an alternative solution for browsers that don't support subgrid yet. By specifically adding conditional styles to browsers that don't support subgrid, we create a situation where when the property does gain support, our code will automatically start using our preferred solution. Once the property gains broad support, we can simply delete our at-rule without needing to touch the rest of our code.
Let's focus on aligning our call-to-action (the link) at the bottom of the projects. Our project already has a
display value of
grid so we will simply provide and alternate value for our
grid-template-rows. Our rule therefore looks as follows (listing 10):
Although not an identical layout as in Firefox, by adding the fallback we now have a working solution in Chrome that will "upgrade" itself to using subgrid once subgrid is supported by the browser (figure 11).
You can find a working version of the code on codepen at https://codepen.io/martine-dowden/pen/yLRawVP.