;

Flexbox Layouts

If there's one thing flexbox excels at, it's twelve-column layouts. In a twelve-column layout, the page is broken into twelve invisible columns. These columns have small amounts of space between them, called gutters. The page is divided into rows, and the containers in the rows take up a certain number of columns.

A twelve-column grid with columns and gutters

If you start to look for them, you'll see twelve-column layouts everywhere. Take a look at these landing pages from Heroku, ChowNow and Square. Notice how the sections are broken up into halves, thirds and fourths?

Examples of twelve-column layouts from Heroku, ChowNow and Square

In this article, I'll show you how to use flexbox's flex-grow, flex-shrink and flex-basis properties to build twelve-column layouts, without the need for a library!

This article is an excerpt from Unraveling Flexbox, a book and video series on building flexbox layouts for the real world. If you like this post, be to check out the full series and subscribe to the Free Flexbox Starter Course.

Setting Up the Container

Let's say you want each of the <div> elements in the following HTML to take up a third of the <section>.

<section>
  <div class="column">First</div>
  <div class="column">Second</div>
  <div class="column">Third</div>
</section>

By default, the <section> element takes up 100% of the width of the screen. Start by limiting its width to 740 pixels. While you're at it, also add some space around the columns.

section {
  max-width: 740px;
  margin: 0 auto;
}

.column {
  margin: 10px;
}

Pop open the code examples and try dragging your browser window until it's smaller than 740 pixels. Notice how the <section> gets smaller as the screen shrinks, but stays fixed when the screen is larger than 740 pixels?

Flexin' It Up

Make the <section> a flex container by setting it's display to flex.

section {
  max-width: 740px;
  margin: 0 auto;
  display: flex;
}

By default, flexbox sets the widths of the columns to the size of their content. You can change this behavior by using the flex-grow and flex-shrink properties.

The flex-grow property tells flexbox how to grow the item to take up additional space, if necessary. flex-shrink tells flexbox how to shrink when necessary. Since we want the columns to behave the same while growing and shrinking, set both of these properties to 1.

.column {
  margin: 10px;
  flex-grow: 1;
  flex-shrink: 1;
}

Woohoo! The flexbox container now fills up three columns. The values for flex-grow and flex-shrink are proportional, meaning they change relative to other items in the flex container. Flexbox adds the values for the properties and then divides each column's value by that sum. So each column takes up 1 ÷ (1 + 1 + 1), or ⅓ of the total space.

What happens if one of the columns has a different value?

.column:first-of-type {
  flex-grow: 2;
  flex-shrink: 2;
}

The first column takes up the same amount of space as the other two. That's because the values add up to 4, so the first column is:

2 ÷ (2 + 1 + 1) = ½

The other two are:

1 ÷ (2 + 1 + 1) = ¼

All About That Basis

If you look closely at the last example, you'll notice that the first column doesn't quite cover half of the container. If you add more content to the third column, you can really see the problem.

<section>
  <div class="column">First</div>
  <div class="column">Second</div>
  <div class="column">
    The third column, with more content than
    before!
  </div>
</section>

What's going on? Why is flexbox not flexing correctly?

It turns out flexbox doesn't distribute space evenly to each column. It figures out how much space each column starts with, specified by the flex-basis property. Then, the remaining space is distributed using the flex-grow and flex-shrink properties.

This might seem confusing, and that's because it is. The way this stuff adds up is really complicated, but don't worry, you don't need to understand the nuances to use flexbox.

Since we don't care about how much space the content originally takes up, set flex-basis to 0.

.column {
  margin: 10px;
  flex-grow: 1;
  flex-shrink: 1;
  flex-basis: 0;
}

.column:first-of-type {
  flex-grow: 2;
  flex-shrink: 2;
  flex-basis: 0;
}

Tah-dah! It works! Well, kind of—there's one last thing to fix.

More Flex Basis

If you add another section below the first, you can see the problem.

<section>
  <div class="column">First</div>
  <div class="column">Second</div>
  <div class="column">Third</div>
</section>
<section>
  <div class="column">First</div>
  <div class="column">Second</div>
  <div class="column">Third</div>
  <div class="column">Fourth</div>
</section>
.column {
  margin: 10px;
  flex-grow: 1;
  flex-shrink: 1;
  flex-basis: 0;
}

section:first-of-type .column:first-of-type {
  flex-grow: 2;
  flex-shrink: 2;
  flex-basis: 0;
}

Why don't the columns line up? It's because flexbox includes the padding, border and margin in the basis when it calculates how big the item should be.

The first and second columns in the second row have 22 pixels between them (20 pixels for the gutter and 2 pixels for the borders). We can add this missing space to the first column in the first row by setting flex-basis to 22px.

section:first-of-type .column:first-of-type {
  flex-grow: 2;
  flex-shrink: 2;
  flex-basis: 22px;
}

Shorthand

Together, flex-grow, flex-shrink and flex-basis form the cornerstone of what makes flexbox flexible. Since these properties are so closely tied together, there's a handy shorthand property, flex, that lets you set all three. You can use it like this:

flex: <flex-grow> <flex-shrink> <flex-basis>;

We can rewrite our CSS to look like this:

.column {
  flex: 1 1 0px;
}

section:first-of-type .column:first-of-type {
  flex: 2 2 22px;
}

Ahh, that's better. Why the 0px in the first flex declaration? There's a bug in Internet Explorer 10 and 11 that ignores flex if the basis doesn't include a unit.

That's It!

You've covered a ton of great stuff in this article, including flex-grow, flex-shrink and flex-basis. You've also seen how these properties can be used to implement twelve-column layouts.

If you're looking for a challenge, try finishing off the entire grid. When you're ready, check the CodePen below to see how it was done.

See the Pen Flexbox 12-Column Grid Example by Landon Schropp (@LandonSchropp) on CodePen.

If you're still confused about how flex-grow, flex-shrink and flex-basis work, don't worry. These properties are the hardest thing to understand about flexbox. You'll be reviewing them again in later lessons, including the next one, where you'll build an awesome video player layout! To make sure you get it, head over to the Free Flexbox Starter Course and sign up. Also, check out my full book, Unraveling Flexbox, for the complete series.