CSS reading-flow: Tab order that matches the layout

Match tab order to visual order without reordering the DOM

Flex reverse and grid areas often put focusable items in a different order than the DOM. reading-flow makes tab and speech order follow the visual layout without shuffling markup or abusing tabindex.

Old wayDOM reshuffle / tabindex
/* visual order via flex reverse, tab order fixed by reshuffling markup */.nav   {  display: flex;  gap: 1rem;}/* HTML rewritten per breakpoint, or tabindex="1/2/3" on each link */
Modern
reading-flow
.nav   {  display: flex;  flex-direction: row-reverse;  reading-flow: flex-visual;  gap: 1rem;}/* tab order follows what you see, not DOM reverse */
Limited availability70% global usage

This feature is not Baseline because it does not work in some of the most widely-used browsers.

Not ready for production without a fallback.

137+
137+

reading-flow ships in Chrome and Edge 137+. Firefox and Safari have no support yet. Keep DOM source order logical so unsupported browsers still get a usable tab path.

Row is reversed visually. Tab still follows Item 1 → 2 → 3 with flex-visual.

flex-direction: row-reverse + reading-flow: flex-visual

Keep sensible markup

Leave the DOM in a logical source order. Change how keyboard and speech travel through the visual layout.

Flex and grid modes

flex-visual, flex-flow, grid-rows, grid-columns, and grid-order each map reading to a layout model.

Fine tune with reading-order

On children, reading-order puts items into ordinal groups when reading-flow: source-order is set on the container.

Old Approach
Reorder DOM or tabindex
Fragile across breakpoints
Modern Approach
reading-flow
Visual order for focus and speech

How it works

By default, tab order and screen reader order follow the DOM. Visual tools like flex-direction: row-reverse or grid-area can make that feel wrong: you see Item 3 first, but Tab still lands on Item 1.

reading-flow: flex-visual on a flex container makes sequential navigation follow the visual order, including writing mode. flex-flow follows the flex flow direction instead. Grid gets grid-rows, grid-columns, and grid-order.

Positive tabindex values are ignored inside a reading flow container. That is intentional. Prefer reading-flow and reading-order over tabindex greater than zero. Firefox and Safari do not support this yet, so keep DOM order sensible as the baseline experience.

ESC