order considered harmful: when flex visual order breaks tab order
· Tags: flexbox, accessibility
The CSS Flexbox spec gives you an order property that lets a flex item declare where it sits among its siblings. Set order: -1 on the third child and it paints first. The HTML stays untouched. That asymmetry is the bug.
What the spec actually says
The CSS Flexible Box Layout Module Level 1 is explicit: “order is solely a presentational concept. Authors must not use order to reorder content as it would alter the meaning of the document.” The same warning sits in the CSS Working Group draft. The spec authors saw this coming.
The accessibility consequence
Browsers tab through the DOM, not the painted layout. A keyboard user reaches focusable elements in source order. A screen reader announces them in source order. A sighted mouse user sees the reordered layout. When those two sequences disagree, you have failed WCAG 2.2 success criterion 1.3.2 Meaningful Sequence. Adrian Roselli's 2015 post “Source Order Matters” is the canonical demonstration: a three-column layout where Tab jumps from column three back to column one looks broken to anyone navigating without a mouse.
The same trap in row-reverse and column-reverse
It is not just order. flex-direction: row-reverse and column-reverse reorder visually with no DOM change. Rachel Andrew flagged this in her 2019 Smashing Magazine piece “Source Order Matters”: any reordering mechanism — flex order, flex reverse, grid placement — needs the same audit. Grid is worse, because grid-template-areas can place an item anywhere on the canvas with the DOM untouched.
When order is fine
The escape hatch is when visual order does not carry meaning. A row of decorative chips, a toolbar of icon buttons that all do equivalent actions, a logo grid — reordering those does not break the narrative. The MDN reference for order spells it out: use it only when the items are interchangeable.
The pragmatic rule
If the user can Tab into any of the items, fix the DOM, not the CSS. If you reach for order to put the “Submit” button last on mobile and first on desktop, you have moved an interactive element across the focus order — that is exactly the case the spec warns about. Move it in HTML, or render twice with aria-hidden, or accept the visual trade.
Flexbox is layout. Layout describes the painting. The DOM describes the meaning. Keep them aligned.
Related
- justify-content vs align-items: which axis is which
- flex-grow, flex-shrink, flex-basis: the three that actually matter
- When to reach for Grid instead
Get FlexFrog on the App Store. Built by Moruk Labs.