CSS Grid layout — crossed sections

An introduction to CSS Grid and its potential with a practical example.

My first contact with CSS Grid was at a talk from Rachel Andrew and I was fascinated by the problems it solves and possibilities it creates. I played around with it a bit and today I want to show you a layout scenario that wouldn’t be trivial to implement without CSS Grid — a layout with intertwined sections.

I will not explore in depth each CSS property, considering this is not meant to be an exhausting tutorial. Instead, I’ll leave some links at the end so you can check more detailed documentation about the properties we use here!

The layout 🐾

For the layout example, we’ll use a fictional social network for dogs (doggos want to meet new doggos every now and then). For each profile, we want to see a name, some info about the pupper, a photo (obviously! 😍), a bio and achievements (like trophies 🏆, they deserve it).

Let’s say that for some reason, the designer behind this very useful platform wants the profile page to have this strange arrangement. Meet Lola, our volunteer doggo:

Icons made by Freepik from www.flaticon.com.

By now, you might have realised this blogpost is just an excuse to show off my cute pupper, but give me some leash! If you don’t like dogs (you cold-hearted cat person 😒), I brought you some CSS as well.

The grid skeleton

There is, of course, a huge number of ways you can define a grid to structure each page or component, accordingly to your needs. Here we want a simple example, so I’m going to use the following structure:

3 rows. 4 columns. Easy peasy lemon squeezy.

Very easy to do with Sketch, also easy to do with CSS Grid. 😄 How would you do this without CSS Grid? Let me know if you find some interesting solution!

Grid container

The first thing you need to do is set your container. That container is where you define the grid itself — columns, rows, gaps, areas, and so on. Only then are the items placed on the grid. This is different from what we‘ve been doing until now — we are used to setting sizes and margins to the items in order to create the aspect of a grid.

So, first things first: display as grid. You won’t see any changes right away because by default the grid only has 1 column. Let’s create some columns and see the changes:

You can use repeat(4, 1fr) or write them all: 1fr 1fr 1fr 1fr, whatever suits you. You can even do repeat(2, 1fr 1fr) ¯\_(ツ)_/¯

By default, each grid item is orderly placed in one cell.

The fr unit indicates the fraction of the remaining space that that item occupies. You can combine it with other units such as % and px.

It’s great because you no longer have to make calculations with percentages while considering the number of columns, amount of margin between items, etc. It adjusts to the overall space you have left and to the spacing you set between the items.

Also, I’ll set the rows to a minimum of 100px (so you can see the grid better when we start placing the elements). But I want the rows’ height to grow accordingly to the content size — in case some dog decides to write an entire book on its bio!

For this result, we use the minmax() function, with 100px on the min value and max-content on the max value. By using max-content, the div will expand to accommodate the content.

Max-content: Represents the largest max-content contribution of the grid items occupying the grid track. [1]
The intrinsic preferred width. [2]

Now, the gaps. We don’t want everything to be so close together, it’s claustrophobic! 😵 I’ve set all the gaps to 10px, but you can specify different values for grid-row-gap and grid-column-gap.

You might have also noticed that gaps only appear inside the grid, they don’t add space around it. For that, you can set margins (that’s what they are after all). And remember, you cannot insert elements into the gaps, not even if you set them to 500px! They are gaps and they are to help. Just add more columns if you need them.

Positioning items on the grid

Now that our container is all set up, it’s time to distribute our content.

But first, you need to know that the items’ placement in the grid is based on the grid lines, not the tracks! Our grid, which has 4 columns and 3 rows, has 5 vertical lines and 4 horizontal lines. If a section occupies an entire row, it goes from line 1 until line 5 of the columns.

We can place items with these properties:

  • grid-column: column-start / column-end;
  • grid-row: row-start / row-end;
Did you notice how the unpositioned elements shift cells?

Or this, for a shorthand:

  • grid-area: row-start / column-start / row-end / column-end;
Notice that grid lets you have blank spaces on the layout without having to use margins.

And many other ways, which you should definitely explore. I’m not going to delve too much into the ways you can place items on the grid, but you can read this for more details. There are several “tricks” that might come in handy.

Here’s an example, take a look at how I placed the trophies ⬇️

-1?! Where the hell is that?

You can count the lines backwards, which is super useful when you don’t know how many rows/columns you have! In this case, I want the trophies section to always go until the last row, even if I were to add more rows to the grid.

The last line is -1 no matter how many lines I have.

The juicy bits

Alright, now we can start inserting the content!

Isn’t she lovely 🎀

You can now see how the rows stretch to accommodate the content (thanks to that minmax() function with the max-content value).

And for the trophies and info sections, I’ll use the Flexbox layout. Grid is not a replacement for Flexbox, they are meant to be used in different situations, though they have some features in common. CSS Grid is designed for two-dimensional layouts (which is our shiny new toy and it’s awesome), but CSS Flexbox is more powerful for one-dimensional layouts (or layouts that would be one-dimensional, if our screens were infinite).

Here are some cases in which Grid works better than Flexbox:

Making literal grids. 🙃
  • Whenever you need a container with columns, rows and gutters. Trust me, fr and grid-gap are your best friends. 
    Say goodbye to those width: calc(100%/7 * 2 — 10px) nightmares!
Page layouts.
  • First, pages are usually two-dimensional layouts. You’d have a harder time recreating this dog social network if you only had Flexbox to work with. And nothing should get in the way of puppers making friends!
  • Also, with Flexbox, the content dictates the layout (you size the elements to create the grid). With Grid, your container dictates the layout. So, Grid works better with slow connections, because things don’t “jump around” while the page loads (see an example).
  • Grid often requires less (or none) media queries to achieve the same responsive result as Flexbox — thanks to minmax(), repeat() and the auto-fills. Lots of bonus points here, way to go Grid! 🙌

So, you can combine them. Grid items can be Flex containers and the other way around. Please note: yes, you could achieve the 1D layout of trophies and info using Grid instead of Flex, but I really want to stress that both can coexist since they have different purposes and strengths.


TL;DR

Here’s what we’ve covered so far. If you want to read more details about it.


That’s all for now! Let me know your thoughts on this layout example and what other cases you found where Grid rocks. 😎 If you’re not here for the CSS at all, here’s a picture of Lola. Thank you for staying with us!


Deemaze Software is a digital agency developing products for web and mobile. Keep track of our work through Twitter, Facebook and Instagram. Also, here’s my Dribbble.

See you around! 🐶