CSS Flexbox explained
Flexbox (or more accurately the Flexible Box Module) is a CSS 3 web layout model.
In (almost) plain English, you can use flexbox to define the layout of the elements within a flex container.
We’ll start with the basics and work through each CSS property. Throughout, imagine there’s an element called .flexbox.
display: flex
The first thing we need to do is set the display property to flex.
.flexbox {
display: flex;
}
flex-direction
Next we need to define which way we want the elements to flow.
You’ve four options:
rowleft to rightcolumntop to bottomrow-reverseright to leftcolumn-reversebottom to top
But what does that really mean? Lets imagine we have four elements within our flexbox.
<div class="flexbox">
<span>1</span>
<span>2</span>
<span>3</span>
<span>4</span>
</div>
Here’s how it’d look. Remember, this applies to left-to-right writing languages only. In right-to-left languages, the row and row-reverse are the other way around.
row
If flex-direction isn’t specified, this is the default behaviour.
| 1 | 2 | 3 | 4 |
|---|
column
| 1 |
|---|
| 2 |
| 3 |
| 4 |
row-reverse
| 4 | 3 | 2 | 1 |
|---|
column-reverse
| 4 |
|---|
| 3 |
| 2 |
| 1 |
flex-wrap
This is an easy one. By default the flexbox container won’t wrap it’s contents.
This means if you’re using flex-row and you have lots of items, it’ll fall off the edge of the page.
flex-wrap gives you the option to make the flexbox child elements wrap, forcing overflowing elements on to a new line.
A new line? In row that's a new line beneath the first but it’d be a new column to the right of the first in column.
.flexbox {
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
No wrapping is the default, but if you need to set it, the value is nowrap.
justify-content
This is how we set the alignment of our flexbox child elements on the main axis.
The main axis the the one we set in flex-direction.
So justify-content aligns items left to right or horizontally in row and top to bottom or vertically in column. And in the -reverse ones too.
Here’s how you centre the items:
.flexbox {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
}
Some other options are (row/column):
flex-start– left/topflex-end– right/endspace-aroundspace-betweenspace-evenly
align-items
Now align-items does the same as justify-content but on the other axis.
So, if you’re using row it does vertical alignment and if you’re using column it’s horizontal.
See list of align-items values here
Size of child elements
The last thing I’ll cover is sizing the flexbox child elements.
You can do this with the shorthand flex property on the child element itself – not the parent .flexbox element.
It sets three separate CSS properties for us:
flex-grow– whether it can be bigger than basis (0 for none, 1+ for growth factor)flex-shrink– whether it can be smaller than basis (as above)flex-basis– the initial width (row)/ height (column)
This part is quite hard to understand if you’re new to CSS/flexbox, so I’ve included some examples to help.
Imagine all the .flexbox child elements have a class name of .flexchild.
Equal size
Each item is an equal size along the main axis (the one you set in flex-direction).
.flexchild {
flex: 1 1 auto;
}
Specific size
If you don’t want one or more of your flexbox children to grow or shrink and instead be a specific size, use the following code.
.flexchild {
flex: none;
width: 240px;
}
Grow and shrink
The flex-grow and flex-shrink numbers are the first two in the flex shorthand property.
They are factors which distribute the remaining space to flex children.
So, if you set all flexbox child elements to flex 1 0 200px, this happens:
- All elements are set to 200px at least
- Elements do not shrink (value is 0)
- The remaining space after elements have been placed is determined
- It is divided by the number of elements
- That number is added to each element
So if we’re using flex-direction: row and the flexbox, we have five 200px width elements and the container is 1000px. Nothing would happen. There’s no remaining space to redistribute.
If the container were larger at 2000px, each child element would grow and be 400px wide.
flex-shrink works in the same way but instead of being concerned with remaining space, it’s the amount the flexbox overflows that is used to calculate how much smaller flex children should be.
You don’t have to set flex-shrink and/or flex-grow to the same number. You might want some elements to take up more or less of the remaning space.
You could set one element to grow by 2 and another by 1. The first would get 66.66% of the remaining space and the other 33.33% – if they’re the only two elements.
That’s it
I don’t think flexbox is nearly as confusing as it first seems and it’s much better than the old system of using inline-block elements or floats.
You should take a look at CSS Grid too.
