Part 2: Thinking about space
Extra space leftovers
As we now move deeper into flexbox, try to think in terms of "What should I do with the extra space?" instead of "How should this thing stretch or shrink?".
For example, using
justify-content:space-between takes the extra space on the horizontal-axis and divies it out between the flex item children.
justify-content:space-around takes the extra space on the horizontal-axis and divies it out between the flex item children – to give equal space on each side.
Notice how the items in the above example "stretched" the entire height of the flex container? That’s because the default align-items setting is "stretch".
Think like this: the flex parent container sees that there is extra space to deal with on the cross-axis. (top to bottom by default) So it checks its align-items setting to see how to resolve it. Since the default value is stretch, it applies that to each child.
Change that flex container align-items value to something like
align-items:flex-start and you get:
This may be a good time to stress the two directional axes (yes, that’s how you spell the plural of axis) in flexbox. So far, we have really only mentioned that justify-content applies to the main-axis(horizontal) and align-items applies to the cross-axis(vertical). Ajusting this becomes important as we are about to cover wrapping.
One last note for alignment on the cross-axis. So far we’ve been talking about flex attributes on the container only . If you want one of the flex items (same thing as saying flex child) to have a different alignment. You can use align-self on the child .
Which way to go? flex-direction & flex-wrap
The easiest example is direction. Thus far, we’ve been using the default which is left-to-right. That’s
but if we want to go top-to-bottom we switch it to
flex-direction: column on our flex container.
Not surprisingly, flex-direction can also reverse the items using values for flex-direction such as "row-reverse" and "column-reverse".
A powerful feature of flexbox is to change the order of items in the flex-direction. By default, all items have an order value of zero. This means that you likely have to change the order of the other ones also – if you want to just change the order of one.
An example might help. Let’s just change the order of the blue-two from 0(default) to 1. Set this on the item :
order: 1 (I sorta expected this to be something like
flex-order: but it’s just
If we wanted that blue-two to be the first item, we could either set it to -1 or apply non-zero order values to the other items.
Let’s talk about wrapping now. In order to keep this simple, and focused specifically on the wrapping behavior of flexbox, we are going to use items of a fixed width/height. It’s simple:
flex:wrap on your flex container.
Unlike working with floats, things don’t just wrap to the left if there isn’t space to fit on a row. Flexbox gives a lot of control over which way things go and how they wrap.
Flexbox items will break out of the container unless we turn on wrap. This first example breaks out on the left because the container is not wide enough and we don’t have any wrapping enabled.
This one wraps horizontally and instead breaks out of the bottom (after it wraps)
Combining the flex-wrap with flex-direction allows layouts that were very difficult before flexbox. Instead of being forced to flow left-right row-by-row, we can do things like flowing top-to-bottom column-by-column.
But let’s start with getting a feel for wrapping, there may be some behavior which will catch you off guard. A simple
flex-direction:row based wrap looks like:
In the example above, notice that the items are flexing to fill the extra space because their default align-items value is "stretch". So what happens if we change this to
Surprised? I was. I expected it to look like this:
The reason is because up until now, we’ve been working with alignment in a single row. Once you wrap into multiple rows, you use align-content on your flex container to deal with the extra space between rows inside your flex container.
This align-content setting is new to us in this guide. Don’t confuse it with justify-content (on the main axis). Rather, think align -content similar to align -items (on the vertical axis).
So, wait! Why is that space there at all? It’s because we’ve triggered more than one row by wrapping. That activates the align-content setting into play which has a default value of stretch . Our container now has multiple rows and that means that flexbox will distribute extra space as needed for each row to stretch. How you align within each row is what align-items speaks to.
Another way to say it:
- Alignment of rows themselves = align-content (doesn’t exist for a single row)
- Alignment within row(s) = align-items
If we wrap into multiple rows, the default align-content:stretch will expand our rows evenly across the height of the flex container. Then align-items will determine how stuff inside of each row vertically aligns.
Because of flexbox, we can easily make something like column-based wrapping by simply changing the flex-direction to column .
When you start to use
flex-direction:column it’s important to realize that you’ve swapped the axis orientation.
If we start with something basic, with just padding on our items and only the flex container having
display:flex we have something like this:
Why does the above example have items that "stretch" from the top to the bottom? Because the default setting for align-items is stretch. When we apply
flex-direction:column to the container, we are swapping the axis. Now align-items is going left-right intead of up-down. Hence:
align-items:flex-start will give something we might expect:
But adding the
flex-wrap:wrap may be confusing:
Why is the above image giving me columns so spread out? Why didn’t
align-items:flex-start fix that? It’s the same issue that we addressed earlier. (right before this "Column confusion" section) Wrapping is introducing new "rows" – in this case "columns" because our flex-direction is column instead of row. Once that happens, align-content arrives and handles space allocation to columns. While align-items manages stuff within a column.
So we drop in
align-content:flex-start to keep the columns aligned together on the left rather than stretched which is the default:
I know this last section may have felt redundant. I rehashed it because I was confused so maybe someone else was too. Dealing with rows-to-columns make me finally appreciate using "flex-start" and "flex-end" rather than left-right-top-bottom.
Now we are equipped to deal with the final (and hardest to understand) part of flexbox. With it, we will be able to flex our items proportionally within our container. The extra spacing will be distributed evenly and non-symmetric items can be aligned with various options. 🙂
< Back to Part 1 Continue to Part 3 >