Avoiding chaos when using Flexbox 'order'
A recent Twitter flurry provoked me to finally build a Flexbox demo I've been meaning to create since I first started playing around with CSS flex properties.
Roma Komarov posted an exploration of using CSS Flexbox and the order
property to create a CSS-only table sorting effect. Some other CSS mavens quickly warned that this was not recommended practice, and was even directly contrary to the spec.
Roma acknowledged the criticism and added a warning to the blog post: just an experiment, don't use in production! But in the Twitter discussion, a few people asked a question that has come up again and again:
What is `order` supposed to be for, then? If its use case is “visual order differs from source” why can’t that be true in other media?
— Seth A. Roby (@TALlama) February 16, 2018
To begin, let's review how you're not supposed to use order
, and why.
The Flexbox specs warn:
Authors must use
order
only for visual, not logical, reordering of content. Style sheets that useorder
to perform logical reordering are non-conforming.
It's pretty rare for CSS specs to order web authors around. Most of their "musts" are reserved for browser developers. So you know that this order about order
is serious business. Keyboard users and screen reader users rely on a consistent order of elements in the DOM, and keyboard or assistive tech users who can see the screen need that order to match the logical order of the elements they see.
Yes, floated layout columns also allowed you (or sometimes forced you) to use source order that didn't match up nicely with the visual order. But that's why we're trying to get away from using floats for layout! Flexbox & CSS grid are supposed to make it easier to use a sensible markup structure—not make it easier to pretend that markup structure doesn't matter.
If you want to reorder the DOM, use DOM methods to move elements around, not CSS methods that only affect layout.
So why does order
exist? Why have an order
property in CSS, if you're not supposed to use CSS to reorder content?
Because sometimes the logical order of a layout cannot be described by Flexbox's normal flow options of left-to-right, right-to-left, top-to-bottom, and bottom-to-top. The order
property is for these cases: to create a visual ordering that does match the logical order, for the design that you're using.
Or in the slightly more elegant words of Flexbox spec editor Elika Etemad (AKA fantasai):
Visual perception doesn't follow coordinate system order. It's affected by things like the gestalt principles, and it has a simultaneity that e.g. speech cannot represent. So we order the source by reading order, and allow visual layout more freedom to move elements around.
— fantasai (@fantasai) February 16, 2018
The Olympic podium in this pen is my favourite example of an unusual layout order that is nonetheless universally recognized. This is the demo that I've been meaning to make for two years. (Convenient that I finally got to it during the Olympics!)
The height of the elements—and cultural familiarity with the podium structure—communicates the rankings, not left-to-right reading order. The source order matches the logical 1, 2, 3 order of the rankings, but the order
property creates the correct layout.
I used a similar center-first order for navigations in the supplementary website for the Using SVG book. My header nav list consists of three items:
- Chapter List
- Previous Chapter
- Next Chapter
When written as a single list, that's the logical order. But the logical layout is to have "previous" on the far left and "next" on the far right, with the table of contents link in between. Flexbox lets me do that without fussing with floats and extra wrapper divs.
The order
adjustment on that site is applied in a min-width media query. On narrower screens, the table of contents link takes up the full first row of the Flexbox layout, and the next/previous wrap to a separate row (or two rows, if the screen is very narrow relative to the font size).
Similarly, I have a max-width media query in my podium pen to remove order
on narrow screens (among other style tweaks) and revert to the normal order of the list for a single-column layout.