Flexbox is a popular CSS layout module that helps you position HTML elements on the screen. There are multiple use cases when it can be a godsend; horizontal and vertical centering is one of them. Flexbox centering solves common alignment problems you might encounter when working with the traditional CSS box model. It allows you to center items within their container both horizontally and vertically with just a few lines of CSS code.
Row vs. Column-Based Flexbox Layouts
Flexbox is a one-dimensional layout module which means that your layouts are based on either rows or columns. You can set the direction of the layout using the flex-direction property you need to use on the flex container. It can take four values: row, row-reverse, column, and column-reverse. This is how the four different flex directions look like on the screen:
Row-based flex layout (default):
<!-- HTML -->
<div class="container">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
/* CSS */
.container {
display: flex;
flex-direction: row;
}
Reversed row-based flex layout:
.container {
display: flex;
flex-direction: row-reverse;
}
Column-based flex layout:
.container {
display: flex;
flex-direction: column;
}
Reversed column-based flex-layout:
.container {
display: flex;
flex-direction: column-reverse;
}
On the illustrations above, you can see single-line flexbox layouts, as we didn’t changed the default value of the flex-wrap property, which is nowrap. So, if you want to display the items in more than one rows or columns, add the flex-wrap: wrap; rule to the flex container, too.
How Does Flexbox Centering Work?
In fact, flexbox doesn’t use the concepts of “horizontal” and “vertical” centering. Instead, it works with main and cross axes, which on the screen, do look like horizontal and vertical centering. The direction of the main and cross axes depends on the value of the aforementioned flex-direction property.
In row-based flexbox layouts (row and row-reverse), the main axis runs in horizontal direction, while the cross axis is vertical. On the other hand, in column-based flexbox layouts (column and column-reverse), the main axis runs vertically, while the cross axis is horizontal. If you are interested more in how flexbox axes work take a look at MDN’s related flexbox documentation.
When we speak about flexbox centering, we speak about two kinds of centering:
- Centering along the main axis (also called block axis).
- Centering along the cross axis (also called inline axis).
If you want a perfectly centered flex item, you need to center it along both axis.
Centering along the Main Axis
You need to use the justify-content property to center flex items along the main axis. Its default value is flex-start which aligns all the items inside the flex container to the beginning of the main axis. If you want to center the items you need to use it with the center value.
In the case of row-based layouts, the following CSS code centers the items horizontally (as here, the main axis also runs horizontally):
.container {
display: flex;
flex-direction: row;
justify-content: center;
}
And, in the case of column-based layouts, the same justify-content property aligns the items vertically (as here, the main axis runs vertically):
.container {
display: flex;
flex-direction: column;
justify-content: center;
}
As in the examples above, we have centered the flex items, the row-reverse and column-reverse directions work in the same way as row and column. This is because the center of the main axis is at the same distance from both the start and end points.
However, note that if you want to use the justify-content property with another value such as flex-end, the resulting layouts will look different when the directions are reversed.
Centering along the Cross Axis
As flexbox is a one-dimensional layout, the cross axis has a secondary role. Flex items flow along the main axis. The cross axis doesn’t change the direction of the flow, just adjusts the items on the screen. There are three CSS properties you can use for centering along the cross axis:
- align-items for single-line centering of all the flex items,
- align-self for single-line centering of an individual flex item,
- align-content for multi-line centering of all the flex items (this property only works when flex items wrap into multiple lines).
Now, let’s see how they work with the different values of the flex-direction property.
1. Single-line Cross Axis Centering
You can use the align-items property to align items along the cross axis. If you use it together with the center property, it centers items vertically when flex-direction is row or row-reverse, and horizontally when flex-direction is column or column-reverse.
This is how centering items along the cross axis looks like in row-based layouts:
.container {
display: flex;
flex-direction: row;
align-items: center;
}
As we haven’t changed justify-content, it takes its default value which is flex-start. In this way, flex items are aligned to the start of the main (horizontal) axis and the center of the cross (vertical) axis:
When working with column-based layouts, you can use the align-items property to center flex items horizontally, as in this case, the cross axis runs horizontally. In CSS:
.container {
display: flex;
flex-direction: column;
align-items: center;
}
Here, the justify-content property also stays at its default value (flex-start). As in column-based layouts, the main axis is the vertical one, flexbox aligns the items to the top of the container (the start of the main axis), while centers it horizontally following the align-items: center rule.
2. Single-item Cross Axis Centering
You can’t only center flex items in bulk along the cross axis, but also opt for centering just one single item by using the align-self CSS property that overrides align-items. You need to add align-self to the individual flex items (instead of the flex container) in the following way:
<!-- HTML -->
<div class="container">
<div class="item"></div>
<div class="item center"></div>
<div class="item"></div>
</div>
/* CSS */
.container {
display: flex;
flex-direction: row;
}
.center {
align-self: center;
background: magenta;
}
As you can see on the screenshot below, it centers the second item along the cross axis (vertically, as it’s a row-based layout). At the same time, the rest of the items stay at their default place:
The example above uses a row-based flexbox layout but align-items works the same way in the case of column-based layouts, too.
3. Multi-line Cross Axis Centering
The flexbox layout module also makes it possible to center multiple lines of items along the cross axis. The align-content property lets you distribute the space around the items when they wrap into multiple lines. It’s a bit hard to understand the difference between align-items and align-content, so let’s see how they compare to each other.
When you set flex-wrap to wrap and only center the align-items property, this is what you get:
.container {
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: center;
}
Although the wrapping flex items are centered along the cross axis (vertically), the space is distributed evenly between them. This is what you can change with the help of align-content in the following way:
.container {
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: center;
align-content: center;
}
As you can see below, the align-content property is responsible for the space distribution along the cross axis. As it has been set to center, the multi-line items are “pulled” towards the center of the flex container as much as possible:
Note that align-content only works when there are more than one lines of flex items. So, you don’t have to worry about it when you have just one or a couple of flex items.
Perfectly Centered Flex Item
To create a perfectly centered layout with flexbox, you need to center it along both the main and cross axes. The most frequent use case is when you center one element inside another element. With flexbox, this is just three CSS rules and it works with any kinds of HTML elements, not just divs:
<!-- HTML -->
<div class="container">
<div class="item"></div>
</div>
/* CSS */
.container {
display: flex;
justify-content: center;
align-items: center;
}
As we haven’t set a value to the flex-direction property, it takes its default which is row:
Besides a single item, you can also perfectly center multiple lines of items with flexbox. You need to use the following CSS in the case of row-based layouts:
.container {
display: flex;
flex-wrap: wrap;
flex-direction: row;
justify-content: center;
align-items: center;
align-content: center;
}
And, this is how the perfectly centered multi-line layout looks like when flex-direction is set to column:
.container {
display: flex;
flex-wrap: wrap;
flex-direction: column;
justify-content: center;
align-items: center;
align-content: center;
}
Conclusion
Flexbox centering allows you to center any kinds of HTML elements inside their container. Adding the display: flex rule to a container comes in handy when you want to center items horizontally, vertically, or both. Flexbox centering is an excellent solution for creating perfectly centered titles, image, video, and product galleries, and more.
There are many CSS techniques and tools that can make your life easier. To learn more about them, take a look at our articles on the 5 things you should know about CSS specifity or check out our collection of the best flexbox code snippets, too.