Adding visual interest with CSS Grid layout

— An article about: - CSS - Grid Layout

If you’ve wandered a bit on this website, you might have ended up on the page displaying my lettering works. It displays a mosaic of my latest artwork entries. It’s basic layout is a grid of square images. It does the job, but it’s visually boring: all images have the same size, they’re all aligned neatly… Having a bit of variation in the sizes of the images would make things a bit more interesting. Something like this:

Basic layout
Enhanced layout

Maybe you see it, maybe you don’t

Rather than using a JavaScript solution to position the images, the layout relies on a recent CSS specification: Grid layout. It leaves the maths for positioning the images to the browsers, following a spec’ed algorithm that would work the same in each of them.

Not all browsers have implemented it yet, though. It means some people will see the nicer layout and others won’t. That’s OK. Everyone will see the images in a good enough layout. The Grid one just providing some final enhancement. And as browser support grows, more and more people will get the nicer one. Progressive enhancement FTW!!!.

So how is that Grid layout different from the other CSS layouts so far?

It lets the parent divide itself into rows and columns which will help position its children. By default, the first child would go into first cell, second child in the second cell… But the grid layout lets you also pick where and how big the children will be displayed. Want the first child to be on the 3rd row, 4th column and span 2 columns wide? The Grid layout has you covered. The other children will then flow back from the first cell.

In practice, let’s see what happens to the artworks page.

Setting up the grid

First, the .rp-ArtworksList-grid element gets divided into a regular grid on 128px squares (1/6th of the total container width).

.rp-ArtworksList-grid {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  grit-auto-rows: 128px;
}

The grid-template-columns property defines how many columns there are and how big they are. If some columns are the same, the Grid layout specification profides a handy way to not type N times the same value with the nice repeat() shortcut. Additionally it introduces a new unit to define lenghts in “fractions of the remaining space”, the fr unit. This makes dividing the width of the grid in 6 equal columns a piece of cake: repeat(6, 1fr).

A corresponding grid-template-rows exists to set the height of the rows. However, grids can also be made to extend automatically, with two properties that let you define the size of new rows (and columns): grid-auto-rows (grid-auto-columns) properties. There’s an auto value that should adapt the height to the children. I couldn’t get it to work well in complement of the padding technique to fix aspect ratios. So hardcoded value it was 🙁

Positionning the children

As it is, the grid is just a replica of the regulare square tiling. To add some visual interest, we still need to move some of the children in specific positions.

.rp-ArtworksList_item:nth-child(1) {
  grid-column-start: 1;
  grid-column-end: span 3;
  grid-row-start: 1;
  grid-row-end: span 3;
}

.rp-AtworksList_item:nth-child(2) {
  grid-column-start: span 2;
  grid-column-end: -1;
  grid-row-start: 2;
  grid-row-end: span 2;
}

...

The 4 properties grid-column-start & grid-column-end, and grid-row-start & grid-row-end define where the element will sit on the grid. You can define these either with row/column numbers, from the start (positive number) or the end (negative number) of the row/column. But you can also set over a span of how many rows/column they should be. This makes it a breeze to position the second big square at the end of the row, twice as big as the small squares, for example.

The layout only used a tiny part of the specification, but it got me really excited about having Grid layout available into more and more browsers. It obviously won’t be one to use for every layout (no need to roll a grid if you just line things up vertically), but it makes creating complex layouts way easier. For now, I’ll keep it at hand for a final layer of enhancement, like on the artworks page.