This article aims to explain the 20% of flexbox that you’ll use 80% of the time.
Flexbox is a way to describe how elements should be displayed inside another element. The outer element is called the flexbox container, and the inner elements are known as flexbox items.
A flexbox container is created by adding a
display CSS property with a value of
flex on it. Any direct child elements inside this container inherently become flex items. A flex item itself could also be a flex container for its child elements, but consider that as a completely isolated flexbox relationship. A flexbox relationship is always a single level deep between a parent element and one or more children.
After declaring your flexbox container, all flex items will by default be placed horizontally next to one another, starting at the left and stretching to the height of the container.
To dictate whether flex items should be laid out horizontally or vertically, you set the
flex-direction property to either
row (horizontal default) or
column (vertical). There are also reverse "row" and "column" options available that will lay items out horizontally, from right to left (
row-reverse) or vertically from bottom to top (
column-reverse), assuming you use a horizontal left to right writing mode.
Assuming you use the default
flex-direction: row declaration. To specify how items should be placed on the horizontal axis (known as the main axis), think about the justification options you normally have in a rich text editor, i.e. aligned left, aligned right or centered. In flexbox, you use the
justify-content property on the container to do the same. The default is
justify-content: flex-start that aligns the items at the start of your main axis. Other possible values are
flex-end, your best friend
center, and lesser-used
To specify how flex items should be placed vertically in the container, on what is known as the cross axis, you use the
align-items property. The available values are very similar to what you get for
justify-content, with a few exceptions:
baseline. By default flex items will stretch the full height of the container. To place items at the top or bottom along the cross axis, use
flex-end respectively. Traditionally, it has been quite hard to vertically centre items using only CSS, but with flexbox, you set
align-items: center and call it a day. The
baseline option is worth knowing about, but you'll use less often. If you have neighbouring flex items containing different sized text and you want to align them based on the bottom of the text, use
Have you noticed that we’ve already catered for most layout requirements, and so far we didn’t specify a single CSS property on any flex item? Everything has been on the flex container. Amazing.
With that said, if you need to align items individually, you can set the
align-self property on an item. It takes all the available values that the container's
It is worth mentioning again that all the examples so far assume a left-to-right writing mode and the default horizontal row flex-direction. When either of these change, the concepts remain the same, only your perspective changes. What I mean is that in a right-to-left writing mode using
flex-direction: column-reverse, items will be justified along the main axis from bottom to top, but now aligned along the cross axis from right to left.
What I’ve found is that it is easier to grasp the fundamentals first using the standard
flex-direction: row. After that, you can swap the flexbox axes around in your mind to visualize how reversed columns would work.
The last flexbox container property worth talking about is
flex-wrap. By default flex items will not wrap to a new row when they run out of horizontal space. They rather get very cosy and squash together as far as possible until the CSS layout engine decides that's enough.
To tell these items rather wrap to a new row, set
flex-wrap: wrap. As I mentioned, the default is
That wraps up all the container properties that we’re going to talk about. The rest of the properties are all set for individual flex items.
The cosy behaviour of flex items to squash together can be overridden with the
flex-shrink property. This property dictates in what proportion an item should shrink inside the container when space becomes scarce. The default is
flex-shrink: 1, which means all items shrink equally. If one of the items is set to
flex-shrink: 2 while the rest keep a value of
1, this item will shrink twice as fast. It is important to note that the value is a unitless value that represents the shrinkage proportion and not something like
In contrast to flex items’ cosy shrink behaviour, they tend to be slightly shy by nature and will not “occupy all spaces” if any free space is available. In more official terms, all flex items have a
flex-grow value of
0 set, which restricts it from growing. Just as with
flex-grow is a unitless value that dictates in which proportion an item should grow within a container if any free space is available. It is important to note that if you have two flex items, one with a
flex-grow value of
1 and the other of
2, that does not mean the one item will be twice as big as the other. It means, from all the available space (if any), the one will receive two portions and the other, one portion.
The final flex item property we’ll cover is
flex-basis. You can think of
flex-basis as the width of an item along the main axis. This property needs to be set with any of the standard CSS units, for example
vw, etc. The default is
flex-basis: auto which means the item takes the width of the content it contains, similar to a
display: inline-block element.
A caveat to this rule is when a
width is specified, in which case the
width would trump the default
flex-basis: auto. Another interesting thing to be aware of is that if you have a
min-width specified along with a non-default
min-width will always take precedence.
Of course, there is a lot more to flexbox, like shorthand syntax for some of the properties we looked at. Feel free to dig deeper once you’re comfortable with these.
Originally published at https://jperasmus.me.