Nic Bovee

Husband, Father, and Solver of Problems.

CSS Garden

Exploring the grid

I've been a long time user of flexbox and now that the grid is fully supported in all browsers, I think it's time for me to get with the program.

To get started let's create a div element with a display:grid property

Box 1
Box 2
Box 3
with a few square divs inside.

So just having display set to grid doesn't really do much... moving on.

What if I use inline-grid

Box 1
Box 2
Box 3
instead?

Cool! I can put grids in the middle of my sentences. Pinch me. I must be dreaming.

Next up, I need to look at grid-template-rows, and grid-template-columns. These let me define the grid lines for the layout. Something like this:

display: grid;
grid-template-columns: 100px 50% 150px;
Box 1
Box 2
Box 3

That's pretty neat! I can set sizes of my columns using any type of unit. Let's try this:

display: grid;
grid-template-columns: 100px 50% 150px 100px;
Box 1
Box 2
Box 3

So this didn't do anything for me, which I think has to do with the fact that I'm asking for 350px of columns + 50% of a 500px box. Let's try this again with a lower percentage:

display: grid;
grid-template-columns: 100px 25% 150px 125px;
Box 1
Box 2
Box 3
Box 4

Very cool. Moving on.

Evidently you can name your gridlines like this:

display: grid;
grid-template-columns: [Cool Starter] 100px [Quarter Pounder] 25% [Big Boi] 150px [Big Boi minus 25px]125px;
Box 1
Box 2
Box 3
Box 4

I'm not entirely sure what this does, but from what I have read it looks like these will be helpful when I start to position children elements.


Moving on to some rows:

display: grid;
grid-template-columns:
[Cool Starter] 100px [Quarter Pounder] 25% [Big Boi] 150px [Big Boi minus 25px]125px;
grid-template-rows: 100px 200px 100px;
Box 1
Box 2
Box 3
Box 4
Box 5
Box 6
Box 7
Box 8
Box 9
Box 10
Box 11
Box 12

Now that we have a handle on how these properties work, lets try some fractional units.

A fractional fr unit allows us to size our gridlines dynamically by adding the total number of fr units and then dividing 1 by that number.

For example if you setup your grid-template-columns to have 4 fractions like this: 1fr 1fr 1fr 1fr, that would be the same as 1 divided by 4 or 0.25.

Box 1
Box 2
Box 3
Box 4

If you resize this window you will see that the columns in this grid resize dynamically with the window.

What's neat about the fr unit, is that you can easily combine it with fixed length units like so.

display: grid;
grid-template-columns: 200px 1fr 1fr 1fr;
Box 1
Box 2
Box 3
Box 4

Now you can see that the left column stays the same size while the right columns collapse as the page shrinks.

Let's talk about minmax() now.

minmax() allows us to define a minimum size for a column or row so that it doesn't get too small.

Take the previous example, but let's say we don't want the second column to get smaller than 100px:

display: grid;
grid-template-columns: 200px minmax(150px,1fr) 1fr 1fr;
Box 1
Box 2
Box 3
Box 4

Notice how as the screen is resized Box 2 shrinks at the same rate as 3 and 4 until it hits the 150px mark and then stops.

As it turns out, the minmax() function can't be applied in reverse, that is, you can't ask for a column to be 1fr up to 500px.

I thought that was a little weird.

But what if we want the columns to size based on the size of the content within... max-content to the rescue!

display: grid;
grid-template-columns: max-content max-content max-content max-content;

Test content.

Test content is getting wider than the picture.

In this case I have some pictures with predetermined widths inside of divs. Notice how when I add content that exceeds the width of the picture, the column expands around it. Neat!

Here's a problem: if I was to set my content like the above but the grid container was smaller than what was required, the content expands past the boundaries of the grid like so:

display: grid;
grid-template-columns: max-content max-content max-content max-content; width: 500px;

Test content.

Test content is getting wider than the picture.

The recommendation around this is to wrap max-content in a minmax() function like so:

display: grid;
grid-template-columns: minmax(0,max-content) minmax(0,max-content) minmax(0,max-content) minmax(0,max-content); width: 500px;

Test content.

Test content is getting wider than the picture.

Next, let's look at fit-content. This one was really tricky to get my head around the first time I saw it. The example from the CSS definitive guide made it easier to understand.

display: grid;
grid-template-columns: fit-content(20ch) fit-content(20ch) fit-content(20ch) fit-content(20ch);

Test content.

Test content that's a little longer.

Test content that's a little longer than the last content that was a little longer than the content before it.

See what's happening? I'm telling the grid to size to the content up to a certain size. So if the content is 1ch big, make the column 1 character big, and size up the column until you reach the 20 character max.

To make a bunch of columns at once, use repeat()

display: grid;
grid-template-columns: repeat(10, 5em);

Test content.

Test content that's a little longer than the last content that was a little longer than the content before it.

You can repeat any sequence you like.

display: grid;
grid-template-columns: repeat(3, 2em 1fr 1fr);
Box 1
Box 2
Box 3
Box 4
Box 5
Box 6
Box 7
Box 8
Box 9

And work your other columns around the repeated colunns

display: grid;
grid-template-columns: repeat(3, 2em 1fr 1fr) 2em;
Box 1
Box 2
Box 3
Box 4
Box 5
Box 6
Box 7
Box 8
Box 9
Box 10