A 10 Step Guide to Flexbox

Flex your Flexbox muscles!

Responsive design got you down? Tired of guessing about Flexbox properties? Follow these simple steps and you’ll never have to copy and paste Flexbox code again.

Step 1: Is Flexbox right for you?

Flexbox is an effective and easy-to-use CSS module for styling HTML elements inside of a parent so that they respond to changes in browser size. This responsiveness is accomplished by setting a variety of properties on both the parent (known as the flex container) and the children (known as the flex items). In so doing, you will be able to control how the flex items are distributed throughout the available space of the flex container, as well as the way in which the flex items grow and shrink in response to changes in browser size.

<div class=”container”>
<div class=”item”>Welcome
</div>
<div class=”item”>to
</div>
<div class=”item”>Flexbox!
</div>
</div>

If your goal is to create a responsive design for your small-scale project, Flexbox is a great option. Simply set display: flex on your flex container in order to get started.

Congratulations! You’ve just begun your Flexbox journey. Now, on to step 2.

Step 2: In which direction would you like the items inside your container to flex?

  • If you want your items to line up in rows, and for your container to flex from left to right, set flex-direction: row on your container. This is the default setting for flex-direction, so setting it explicitly isn’t necessary. Nevertheless, I find it helpful to declare it anyway, in order to remind myself that direction is important.
  • If you want your items to line up in rows, but you want your container to flex from right to left, use flex-direction: row-reverse on your container.
  • If you want your items to line up in columns, and for your container to flex from top to bottom, use flex-direction: column on your container.
  • If you want your items to line up in columns, and for your container to flex from bottom to top, use flex-direction: column-reverse on your container.

Once you’ve chosen your flex-direction, proceed to step 3.

Step 3: How would you like your flex items to line up along the main axis?

Now, you must choose how you would like your items to line up parallel to your flex-direction. This is accomplished with the justify-content property on the flex container. If your flex-direction is set to row or row-reverse, justify-content specifies how your items are positioned horizontally. If your flex-direction is set to column or column-reverse, justify-content specifies how your items are positioned vertically.

When discussing Flexbox layouts, we often use the terms main axis and cross axis. The main axis is the axis that runs parallel to the flex-direction, and the cross axis is the axis that runs perpendicular to the flex-direction. So, if your flex-direction is set to row or row-reverse, the main axis will be the x-axis. If your flex-direction is set to column or column-reverse, the main axis will be the y-axis. The justify-content property, therefore, refers to the alignment of flex items along the main axis.

With all this in mind, let’s go over the different values you can assign to the justify-content property.

justify-content: flex-start

  1. If your flex-direction is set to row, justify-content: flex-start will position your flex items flush left within your flex container. (When thinking about justify-content with this default flex-direction, it’s helpful to remember that we start reading on the left).
  2. If your flex-direction is set to row-reverse, justify-content: flex-start will position your flex items flush right within your flex container, since flexing starts on the right and goes to the left.
  3. If your flex-direction is set to column, justify-content: flex-start will position your flex items at the top of your flex container. Remember, justify-content refers to the alignment of items along the main axis (that is, the alignment of items parallel to the flex-direction). Since flex containers with flex-direction values of column or column-reverse flex up and down (along the y-axis), justify-content will align items in the same way.
  4. If your flex-direction is set to column-reverse, justify-content: flex-start will position your elements at the bottom of your container.

justify-content: flex-end

  1. If your flex-direction is set to row, justify-content: flex-end will position your flex items flush right within your flex container.
  2. If your flex-direction is set to row-reverse, justify-content: flex-end will position your flex items flush left within your flex container.
  3. If your flex-direction is set to column, justify-content: flex-end will position your flex items at the bottom of your flex container.
  4. If your flex-direction is set to column-reverse, justify-content: flex-end will position your flex items at the top of your flex container.

justify-content: center

  1. If your flex-direction is set to either row or row-reverse, justify-content: center will center your flex items horizontally.
  2. If your flex-direction is set to either column or column-reverse, justify-content: center will center your flex items vertically.

justify-content: space-around

  1. If your flex-direction is set to either row or row-reverse, justify-content: space-around will distribute the remaining space on the left and right sides of your flex items.
  2. If your flex-direction is set to either column or column-reverse, justify-content: space-around will distribute the remaining space on the top and bottom sides of your flex items.

justify-content: space-between

  1. No matter your flex-direction, justify-content: space-between will evenly distribute the remaining space between the flex items.

Now, on to step 4!

Step 4: How would you like your flex items to line up along the cross axis?

Now that you’ve decided how your flex items will be positioned along the main axis (that is, parallel to the flex-direction), it’s time to decide on how they will be positioned along the cross axis (that is, perpendicular to the flex-direction). This is accomplished by setting the align-items property on the flex container. If your flex-direction is set to row or row-reverse (remember: this means your container is flexing along the x-axis), align-items will determine the vertical positioning of your flex items (that is, their positioning along the y-axis). If your flex-direction is set to column or column-reverse (remember: this means your container is flexing along the y-axis), align-items will determine the horizontal positioning of your flex items (that is, their positioning along the x-axis). Let’s go over the different options for align-items.

align-items: flex-start

  1. If your flex-direction is set to either row or row-reverse, align-items: flex-start will position your flex items at the top of your flex container.
  2. If your flex-direction is set to either column or column-reverse, align-items: flex-start will position your flex items on the left hand side of your flex container.

align-items: flex-end

  1. If your flex-direction is set to either row or row-reverse, align-items: flex-end will position your flex items at the bottom of your flex container.
  2. If your flex-direction is set to either column or column-reverse, align-items: flex-end will position your flex items on the right hand side of your flex container.

align-items: center

  1. If your flex-direction is set to either row or row-reverse, align-items: center will vertically center your flex items (i.e., center them along the y-axis).
  2. If your flex-direction is set to either column or column-reverse, align-items: center will horizontally center your flex items (i.e., center them along the x-axis).

align-items: stretch

  1. If your flex-direction is set to either row or row-reverse, align-items: stretch will cause your flex items to stretch out vertically (i.e., along the y-axis), so that they fill the entire height of the flex container.
  2. If your flex-direction is set to either column or column-reverse, align-items: stretch will cause your flex items to stretch out horizontally (i.e. along the x-axis), so that they fill the entire width of the flex container.

On to step 5!

Step 5: Do you want one flex item to have its own distinct positioning along the cross axis?

There may be times in which you want the positioning of one item along the cross axis to differ from that of the other items. Enter: align-self! While the the properties we’ve discussed thus far are set on the flex container, align-self is a property on individual flex items (that is, the children of the flex container). It takes the same values as align-items, and the value of an individual item’s align-self property will override the value of the container’s align-items property.

In the below example, the align-items property of the flex container is set to center, but the align-self property of the blue div is set to stretch.

Now, for step 6!

Step 6: Do you want your flex items to grow when the amount of available space increases?

The most valuable aspect of Flexbox is that it allows you to dynamically alter the height or width (depending on the container’s flex direction) of the flex items in order to fill the available space. This is important because the amount of available space in a container is likely to vary across screen sizes. The flex-grow property, which is set on the flex items, is critical to this aim; it allows you to set the ratio according to which the flex items will grow along the main axis as the container size increases. For instance, if you set flex-grow to 1 on all of your items, they will grow to fill the available space at the same rate.

Each of the flex items in this example have their flex-grow property set to 1.

If, however, you set flex-grow to 2 on one of your items, and leave the others set to flex-grow: 1, the item set to flex-grow: 2 will grow to fill the available space at twice the rate of the others. It’s important to understand that the item set to flex-grow: 2 does not grow to be twice the size of those set to flex-grow: 1; rather, it simply grows twice as fast.

The red and green divs have their flex-grow property set to 1, while the blue div has its flex-grow property set to 2.

The default for flex-grow is 0, so if you want your items to grow, you’ll have to tell them explicitly. Additionally, when your flex items are set to grow, that means they’re filling all the available space along the main axis. As such, there’s no need to set justify-content on the flex container. If you do, it will have no effect.

Step 7: Do you want your flex items to shrink when the amount of available space decreases?

Just as flex-grow allows you to dynamically increase the height or width (depending on the container’s flex-direction) of the flex items when the amount of available space increases, flex-shrink allows you to dynamically decrease the height or width of the flex items when the amount of available space decreases. Like flex-grow, flex-shrink also makes use of ratios to determine how quickly elements should shrink when there isn’t enough available space to contain them. If you set one flex item to flex-shrink: 1 and another flex-item to flex-shrink: 2, the flex item that has flex-shrink: 2 will shrink at twice the rate of the one with its flex-shrink property set to 1.

The red and green divs have their flex-shrink property set to 1 (the default), while the blue div has its flex-shrink property set to 2.

flex-shrink: 1 is the default setting, so all of your flex items will shrink at the same rate unless you tell them otherwise. And because 1 is the default value for flex-shrink, you must explicitly set flex-shrink: 0 if you don’t want an item to shrink at all.

It’s important to note that a single flex item can shrink and grow; its responsiveness is not restricted to one or the other. Additionally, items can shrink and grow regardless of the flex-direction of the flex container.

Onwards!

Step 8: Do you want your flex items to have a default size, before growing and shrinking happens?

In the world of Flexbox, the flex-basis property, which can be applied to the flex items, acts as a fancy version of width (if the container’s flex-direction is set to row or row-reverse) or height (if the container’s flex-direction is set to column or column-reverse). You can think of an item’s flex-basis as the ideal amount of space an item will take up before it is forced to grow or shrink. If present, it will override the width or height property of the flex item in question.

flex-basis has certain limits. Let’s imagine that we have a flex container with a flex-direction of row (remember: this means that flex-basis adjusts the flex items’ widths). If the flex items inside that container have a min-width is specified, that value will act as the lower limit for flex-basis. This means that if flex-basis is set to 200px, but the min-width is 300px, the flex item will never get narrower than 300px. Similarly, max-width will act as an upper limit for flex-basis. This means that if flex-basis is set to 500px, but the max-width is set to 400px, the flex item will never get wider than 400px.

In addition to accepting values in pixels, flex-basis can also accept values as percentages or rems.

Just a few more steps…!

Step 9: Do you want your items to wrap onto another line instead of shrinking if there’s not enough room for them on the first line?

It’s not always advantageous for your flex items to keep shrinking as the amount of available space decreases. What if, for example, you were trying to render a collection of recipe cards, and each card had ingredients and directions listed on it? The cards would become illegible — not to mention smushed — if they kept shrinking while remaining on the same line.

Thankfully, the flex-wrap property exists! Simply set it to flex-wrap: wrap on your flex container, and your flex items will never get smaller than their width/height (or flex-basis). Instead, when there’s no longer enough room for all the flex items at their predetermined width/height (depending on flex-direction), they will wrap onto the next line. Wrapping happens along the main axis, so if your flex-direction is set to row or row-reverse, the rows will run horizontally (like the lines on a page). If your flex-direction is set to column or column-reverse, the rows will run vertically (like, well, columns).

In the below example, each div has a flex-basis of 200px, and they are not set to grow. Because flex-wrap: wrap is set on the flex container, the items don’t shrink, either; once there’s no longer room for the 200px-wide divs on a line, they wrap to the next one.

Keep going — you’re almost there!

Step 10: Time to make it even better!

Give yourself a pat on the back — you made it to the end! Now that the hard parts are behind you, it’s time to refactor your Flexbox code so that it’s even more eloquent than before. This can be accomplished with the use of two “shorthand” properties: flex and flex-flow.

The flex property combines flex-grow, flex-shrink, and flex-basis by taking values for each — in that order. For example, your flex property might look something like this: flex: 1 2 200px. You can omit the second two values if you want, but if you do, it’s important to remember the default behavior for flex. Omitting the second value (i.e., the value for flex-shrink) is pretty straightforward; it will default to 1, just as flex-shrink normally does. Omitting the third value, however (i.e., the value for flex-basis) is a little more complicated. When set on its own, the flex-basis property defaults to auto. However, if you omit a flex-basis value when using flex, flex-basis will default to 0px.

If you want to streamline things even further (and you’d like your flex item to have its flex-grow property set to 1, its flex-shrink property set to 1, and its flex-basis property set to auto), you can use flex: auto. And if you’d like your flex item to have its flex-grow and flex-shrink properties set to 0 and its flex-basis property set to auto, you can use flex: none.

The flex-flow property combines flex-direction and flex-wrap — in that order. For instance, you can set flex-flow: column wrap and omit the flex-direction and flex-wrap properties.

Conclusion

Now that you’ve mastered the basics of Flexbox, it’s time to get out there and practice, practice, practice. You can even experiment with order and align-content, while you’re at it. Best of luck — and keep flexing!

References