Łukasz Makuch

Łukasz Makuch

The new CSS Grid will change the way you think about layouts. Here's why.

The first CSS Grid Layout made it possible to divide the area of an element with horizontal and vertical lines. These lines dictated the size and position of its children.

But this is going to change.

To understand why, and most importantly, how, let's recap the way things worked in the first version of the grid.

For instance, this card could be one grid:

The first card

The HTML code looks simple. It's just one parent with two children:

<div class="card">
  <img class="avatar" src="https://picsum.photos/id/10/200/200"/>
  <h2 class="card__text">Lorem Ipsum</h2>
</div>

The CSS code makes the parent element a grid:

.card {
  display: grid;
  grid-template-columns: max-content 1fr;
  grid-gap: 10px;
  align-items: center;
}

The grid lines are as follows:

The first card's grid

Another card could be another isolated grid:

The second card's grid

And the header could be yet another grid, built in the same way:

The header's grid

Let's put the previously discussed components together, just like that:

The current grid, all cards with the same data

The parent element is yet another grid, just to define the spacing among the cards and the header:

.grid {
  display: grid;
  grid-gap: 20px;
}

It doesn't look bad.

However, it's quite optimistic to assume that in real life all the cards will have identical content. So let's make it a bit more realistic:

The current grid, real-life data

That's the problem I wanted to show you. As we can see, the texts are not really aligned with each other:

The current grid, real-life data, with a keyline

Luckily for us, the new CSS Grid Layout provides an elegant solution to this ugly problem!

We can define a single grid line that will be used to divide all the cards and the header together, on a higher level, above the individual elements:

The new CSS grid, grid vizualisation

First, let's define one grid at the parent's level instead of defining multiple grids for each child:

.grid {
  display: grid;
  grid-template-columns: max-content 1fr;
}

Then it's enough that we use the new subgrid option. It means that both the .header and the .card elements don't define their own grid lines, but instead, they inherit them from their parent element:

.header {
  /* 1 / -1 to make it span across the whole container. */
  grid-column: 1 / -1;
  grid-template-columns: subgrid;
}

.card {
  grid-column: 1 / -1;
  grid-template-columns: subgrid;
}

And... that'd be it!

The new CSS grid

The complete code of this example may be found on CodePen.

Subgrids from CSS Grid Level 2 enabled us to define cross-component alignment rules that work well even for dynamic content.

Just to be fair, I got to say that designers have been talking about it for ages! Maybe they called it differently, like keylines in Material Design, but anyway, it's nothing new to them!

So is the new specification a spacing nirvana? Not yet. By looking at some ongoing discussions about possible extensions of the subgrid we can tell that there's still some room for improvement. But it's already a big step towards unifying the ways designers and developers think. Now when somebody says "We need to align these components to this line." we can actually code "this line".