Mastery Games

The Shiny New Grid Tools

Flexbox is amazing, works even in older browsers, and mastering it will do a lot for you. But there's a new kid on the block. CSS Grid makes possible some layouts that are either impossible to achieve with Flexbox or that would take a ton more work.

Besides being completely awesome for full page and responsive layouts, CSS Grid comes packed with some incredible new tools that make a web dev feel like a freaking rockstar. Check out these new weapons at your disposal as soon as you start using Grids:

Gaps

Grid gaps are like margins on steroids. You can set gaps between your rows and columns, and the gaps are wicked smart: they only apply to the inner tracks! Our outer tracks stay flush against the edges like we want them to 99% of the time.

.container {
  display: grid;
  height: 300px;
  grid-gap: 30px;
}

We used to have to get this by disabling margins on the first or last child element. But then we also had to worry about what happened when the content shifted to multiple lines making the last child no longer the one that needed its margin removed. It was a pain train, and gaps now handle it for us automatically. It's almost as if someone who built this stuff actually uses CSS themselves!

The CSS spec people have recently realized that gaps would be incredibly useful even in flexbox layouts. So they've made the grid- prefix optional and are currently working to enable gaps in flexbox. But for now it's only available when using Grid.

Named Grid Lines

Grid gives us a brand new way to size and position everything that goes into the grid. You can make items span forwards or backwards, overlap with other items, span multiple columns or rows, etc. It really is a much better layout system than anything we've had in the past. Check out Naming your CSS Grid Lines for all the juicy details.

Fraction Units

Grids come with a brand new fr unit that can only be used in a grid. They're very different from percentages and viewport units (vw, vh) etc. When you assign a column or row a fraction unit, it simply means take up a certain fraction of the free space left over after all of the other tracks and gaps take their fixed space.

Check it out. In this example we're telling the first (orange) column to be 50px wide, our grid to have 10px gaps between tracks, letting the second (blue) column take up 1 fraction of the remaining space, and the last (purple) column take up 2 fractions of the remaining space.

.container {
  display: grid;
  grid-gap: 10px;
  grid-template-columns: 50px 1fr 2fr;
}

If you're curious, the math looks something like this:

gridWidth = 300px
totalGaps = gridGap (10px) * 2 = 20px
column1Width = 50px
freeSpace = gridWidth - totalGaps - column1Width = 230px
numFRUnits = 3 (the sum of all the fr units used in the grid columns)
column2Width = freeSpace * ( 1(fr) / numFRUnits) = 230 * (1 / 3) = 76.66px
column3Width = freeSpace * ( 2(fr) / numFRUnits) = 230 * (2 / 3) = 153.33px

These fr units are legit. They place nicely with all the other units. And unlike percentages which are based on the size of the Grid container, fractions are based only on the free space that's left. So you won't accidentally cause overflow/scroll issues like you might if you used percentages.

NOTE: It's easy to think fr units are just like flexbox's flex-grow, but there's a big difference. We'll cover that in a future post.

Minmax

One of my favorite new things that comes with Grid is the minmax value. It lets you set ranges of values for your Grid columns & rows. See grid is perfect for responsive layout for an example of minmax. This is such a smart unit, I'm really hoping to see it come to more parts of CSS in the future. Imagine being able to set a range for your padding: at least 10px but no more than 10%. We can kinda do this on a few properties today using min-width and max-width but not on things like border / margin / padding / flex-grow / box-shadow etc. and it's just not as flexible as minmax.

Implicit Tracks

Something way cool about Grids is that you don't need to explicitly spell out a new column or row for each item that will go into your grid. You just define the template using grid-template-rows and grid-template-columns. As soon as your grid has more stuff in it than what you defined, the smart little devil will go ahead and create new columns & rows beyond what you specified!

Watch this: we only define two columns and one row (two cells total). But as soon as a third item went into the grid it created a new second row automatically:

.container {
  display: grid;
  grid-gap: 10px;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 1fr;
}

The reason our purple item is so small is because these implicit (auto-generated) tracks default to a size of auto. Since the purple item doesn't have any content, its only size are its borders. But the smart Grid spec people totally threw us a bone here: we can actually specify exactly how we want any auto-generated implicit tracks to behave!

Here's the exact same example but this time telling our Grid to make any new rows take up an equal share of the available space, using grid-auto-rows: 1fr;

.container {
  display: grid;
  grid-gap: 10px;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 1fr;
  grid-auto-rows: 1fr;
}

Sweet right? Our new implicit row forced our original first row to stop hogging all the space. What do you think would happen if we had set grid-auto-rows to a fixed unit, like 50px? Play with this example (it's live on the site or you can go to codepen) and see what happens.

I love the granular control Grid layout gives us. I used a lot of implicit rows like this when I built my new grid site.

True Column Flow

I once bombed a job interview question many years ago where I was asked to create a "column layout": to make items fill up entire columns first rather than rows first. But the DOM doesn't work this way: it always places elements horizontally:

.container {
  width: 300px;
  height: 300px;
}

.item { 
  width: 50%;
  float: left;
  height: calc(300px / 3);
}

Turning this into a true column layout used to take some JavaScript chops that I clearly didn't have at the time. But with CSS Grid it's now super easy using the grid-auto-flow property:

.container {
   display: grid;
   grid-auto-flow: column;
   grid-template-columns: 1fr 1fr;
   grid-template-rows: 1fr 1fr 1fr;
   width: 300px;
   height: 300px;
 }

This made it fill up the left column first rather than the row first, and any new items that get added will make the grid create new implicit columns instead of implicit rows. See! It wasn't that I was a complete n00b of a dev, I must have just known in my heart that someday CSS would get awesome enough to do this kind of thing for me ;)

And More

Grid layout brings so many great new tools to our kit! In a future post I'll cover how awesome grid areas are, justify-self (you know, that thing you tried a million times with flexbox but it simply doesn't have it), and other amazing goodies. Students of Grid Critters are mastering all of it in the most fun way possible, you should join us.

Have fun playing with all these shiny new Grid tools!

Grid Critters Game

Master CSS Grid right from the start by playing this new mastery game. You'll learn the ins and outs of Grids one fun level at a time, while saving an adorable alien life form from certain destruction.Master CSS Grid