We have already seen what Flexbox is. Now we need to look at the alignment properties, which are rules for distributing and aligning child elements within a flexible container.
These properties allow us to create fluid and adaptable layouts without having to do manual mathematical calculations, delegating all the heavy positioning work to the browser engine.
As we saw in the previous post, display: flex is the rule that transforms a normal box into an elastic container.
Without it, none of the other properties we are about to see will have the slightest effect. It is the power button that enables the entire Flexbox engine for the elements that live directly inside that box.
Alignment on the Main Axis (justify-content)
The justify-content property takes care of distributing the children along the main axis (which, if you haven’t changed it, is the horizontal line from left to right).
.navigation-menu {
display: flex;
justify-content: space-between; /* Ideal for separating the logo on the left and the links on the right */
}
It is the perfect tool for deciding what to do with the leftover space that remains in the row. Its most commonly used values are:
| Value | Description |
|---|---|
flex-start | This is the default behavior. It pushes all items towards the start of the line (the left). |
flex-end | Pushes all items towards the end of the line (the right). |
center | Groups all items in the absolute center of the container. |
space-between | Sticks the first item to the start, the last item to the end, and distributes the remaining space equally between the middle ones. |
space-around | Similar to the previous one, but adds a little space on the ends as well. |
Alignment on the Cross Axis (align-items)
On the other hand, the align-items property controls how the items behave on the perpendicular axis (usually, the vertical one).
If you have a row of boxes and some are taller than others, this property dictates how they should be vertically aligned with each other.
| Value | Description |
|---|---|
stretch | This is the default value. If you haven’t given the children a fixed height, they will automatically stretch to fill the entire height of their parent. |
flex-start | Aligns them all resting on the “ceiling” of the container. |
flex-end | Aligns them all resting on the “floor” of the container. |
center | Centers them vertically, ignoring whether they touch the top or bottom. |
By combining justify-content: center and align-items: center in a container that takes up the full screen, you will achieve the long-sought perfect horizontal and vertical centering that made past generations of programmers suffer so much.
Controlling Overflow (flex-wrap)
What happens if we try to put 10 boxes of 200 pixels wide on a mobile screen that only measures 400 pixels?
By default, Flexbox is very stubborn. It will try to keep all children on one line no matter what, squashing them and reducing their size until they fit (or horribly overflowing the screen).
To avoid this disaster, we use the flex-wrap property.
.photo-gallery {
display: flex;
flex-wrap: wrap; /* We give it permission to create new rows */
}
By giving it the value wrap, we are telling the browser: “If you see that the elements don’t fit with their original size, put them on a new line below”. This is a very important property to ensure your website doesn’t break on small screens.
The Inner Spacing (gap)
Back in the day, to separate two elements inside a Flexbox, we had to give them a margin and then do weird calculations so the last element wouldn’t push against the container’s edge.
Fortunately, nowadays we have the gap property.
.card-container {
display: flex;
gap: 20px; /* Perfect and automatic separation */
}
This property adds an empty space of 20 pixels exclusively BETWEEN the child elements, ignoring the outer edges (it is the modern, clean, and recommended way to separate things).
Properties on the Children: flex
So far, we have given orders to the parent container. But the children can also have a say. The shorthand flex property controls how each element grows or shrinks within the available space.
.card {
flex: 1;
}
With flex: 1, all children try to distribute the available space evenly.
.primary {
flex: 2;
}
.secondary {
flex: 1;
}
In this case, .primary will request approximately twice as much space as .secondary. It is not a fixed measurement in pixels, but a proportion within the flexible container.
Aligning a Specific Child with align-self
Sometimes we want all children to be aligned the same way, except for one. For that, there is align-self.
.container {
display: flex;
align-items: center;
}
.special-button {
align-self: flex-end;
}
align-self overrides the parent’s align-items only for that specific element. It is very useful for small adjustments without dismantling the entire structure.
