A Comprehensive Guide to Flexbox Ordering & Reordering
The flexbox layout module allows us to lay out flex items in any order and direction. Flexbox ordering is, in fact, easier than ordering with floats or CSS grid, even if you might not think so at first. As flexbox is a one-dimensional layout model, as opposed to CSS grid which is two-dimensional, you only have to pay attention to one direction. The rules are also clearly defined by W3C, so you don’t have to deal with the usual mess of floats and clearfixes.
By reading this guide, you’ll learn how to use the following flexbox properties for ordering purposes:
Ordering Vs. Reordering
When talking about flexbox ordering, we need to make clear the difference between ordering and reordering.
What is Ordering?
When we set up a flexbox layout we first need to define the source order, meaning we have to decide how the axes of the flex container are positioned. I wrote in detail about how flexbox axes work in my guide about flexbox alignment.
In brief, each flex container has two axes: the main axis and the cross axis. The main axis will have one of four directions, and the cross axis will always be perpendicular to that:
left to right
right to left
top to bottom
bottom to top
We set up the main axis with the flex-direction property, then we decide how flex items will wrap, using the flex-wrap property. These two properties determine how the browser will lay out the items within the flex container.
So What is Reordering?
Flexbox also lets us manipulate the default source order, effectively reordering, with the help of the order property. Reordering means that we change the visual rendering of the items, while the source order remains intact.
If we use the reordering capabilities of flexbox, we don’t have to change the HTML document structure just for the sake of visual presentation. So, screen reader users (and search engines) can get the content in a logically structured way (e.g. the sidebar won’t take precedence over the main content).
Flexbox ordering happens with the flex-direction and flex-wrap properties. Flex-direction specifies the direction of the main axis. It can take the following values:
row (default) main axis: left to right
row-reverse main axis: right to left
column main axis: top to bottom
column-reverse main axis: bottom to top
Flex-wrap defines if flex items are laid out in a single line or wrap to multiple lines. It also controls the direction of the cross axis. It can have three values:
nowrap (default) lays out flex items in a single line; the cross axis stands in the default position
wrap lays out flex items in multiple lines; the cross axis stands in the default position
wrap-reverse lays out flex items in multiple lines; the cross axis is reversed
The default position of the cross axis is:
top to bottom in case of row and row-reverse
left to right in case of column and column-reverse
In my previous article about flexbox alignment, you can find four detailed examples (with demos) about how to set up the main axis in four different directions using flex-direction. However, when discussing flexbox ordering, I think it’s more important to know how to use the flex-direction and flex-wrap properties together to achieve the source order we are looking for.
A Quick Code Example
We’ll use a simple code example to see how flexbox ordering works. The HTML here consists of just a few divs:
The .container div will be the flex container and the divs with the .item class will be the flex items. We’ll use (almost) the same CSS in all examples, just the flex-direction and flex-wrap properties will change. Here’s how our CSS looks with the row and wrap values:
Now, we’ve reached the really interesting part! It’s not too difficult to understand flexbox ordering in theory, but using it in practice can certainly be a challenge. This happens because it’s difficult to see how different variations of flex-direction and flex-wrap compare to each other.
In the embedded pen below, you can see how the flex-direction: row and flex-direction: column layouts work together with different values of the flex-wrap property. Use the form controls to see different combinations.
As you can see, when flex-direction is row, flex items are laid out horizontally, from left to right. When we use wrap-reverse instead of wrap, flexbox starts laying out the items from the bottom, instead of from the top. This happens because wrap-reverse reverses the direction of the cross axis.
When flex-direction is column, items are laid out vertically, from top to bottom. And, when we use wrap-reverse instead of wrap, flexbox starts laying out the items from the right (now this is the starting point of the cross axis), instead of from the left.
Ordering With row-reverse and column-reverse
Now, let’s have a look at how flexbox lays out items when flex-direction is row-reverse and column-reverse.
As you can see in the demo above, flexbox starts laying out the items from the start of the main axis in both cases, just like before. The main axis of the row-reverse layout runs from right to left, so flexbox starts laying out the items from the right. And, the main axis of the column-reverse layout runs from bottom to top, so items start to flow from the bottom of the flex container.
When we use flex-wrap: wrap, flexbox starts to wrap the items from the top when flex-direction is row-reverse and from the left when it’s column-reverse, as these are the starting points of the cross axis in the respective cases.
When we flip the wrapping direction to flex-wrap: wrap-reverse, the cross axis will run in the opposite direction. It will point from bottom to top when flex-direction is row-reverse, and from right to left when it’s column-reverse.
Speed Things Up With the flex-flow Shorthand
CSS also has a cool shorthand for the flex-direction and flex-wrap properties. It’s called flex-flow. To use it, we need to list the two properties after each other in the following way:
The order property changes the default ordering of flex items that we define with flex-direction and flex-flow. It only affects the visual rendering of the items, so it doesn’t affect the way how screen readers and other non-CSS user agents read the source code.
As opposed to the properties mentioned before, we use order on the flex items, instead of the flex container. It can take any integer value, and its default value is 0.
The following example moves .item-3 to the starting point of the main axis. As all items have 0 as default value, it’s enough to use the order: -1 rule to make it the first item within the container:
You’ll notice that we can use the same logic to move .item-3 to the end of the main axis. We only need to define a positive order value for it.
Of course, we can reorder as many of these flex items as we wish (though keep in mind that reordering everything probably isn’t the most accessibility-friendly decision ever). The order properties of the different flex items are always relative to each other. Below, you can see how to reorder multiple items within the flex container.
The most important thing to understand about all this is that the order property doesn’t affect the painting, speech, and sequential navigation orders. This means that when we modify the order of our flex items, users of non-visual media won’t experience the changes. For example, people relying on keyboard navigation will still move through the links in the original source order.
This flexbox behavior can come in handy in some cases. For instance, it’s possible to make the so-called “Holy Grail Layout” accessible with the help of flexbox ordering. The Holy Grail Layout is the popular blog layout with a header, a footer, and two sidebars: one on the left and one on the right of the main content.
In this layout, we usually put the left sidebar before the main content in the HTML code. However, from the point of view of accessibility, users of assistive technologies should encounter the main content first. Flexbox is perfect for this. We can place the main content before the two sidebars in our markup. Then, we only need to put the sidebar and the main content into the correct position using the order property:
Everything said in this tutorial applies to the LTR (left to right) writing mode. Flexbox axes actually follow the document’s writing direction, which can be set up with the direction and writing-mode properties. This is why in LTR writing mode, the main axis runs from left to right when flex-direction is row. In RTL writing mode it runs in the opposite direction, from right to left, and everything else changes accordingly.
That’s a (Flex) Wrap!
This tutorial was the second part of my flexbox series. Make sure you read the first part about flexbox alignment, to learn how to align flex items along the main and cross axes. If you want to know more about flexbox ordering, MDN has a very informative article on the subject as well.