The CSS reading-flow property (Chrome 137+) solves the accessibility problem where visual order (set by CSS Grid or Flexbox) diverges from DOM order — causing keyboard focus and screen reader reading order to follow the source order rather than the visual layout. With reading-flow, focus navigation follows the visual order without requiring JavaScript or DOM reordering.
Problem: CSS Grid and Flexbox lay out items visually in a different order from the DOM — order and grid-template-areas can move items visually without changing the HTML order — causing a mismatch between visual reading order and keyboard tab order for screen reader users.
Solution: Use the CSS reading-flow property (shipping in Chrome 137+) to declare the intended reading order of a flex or grid container: reading-flow: flex-visual or reading-flow: grid-rows. The browser adjusts keyboard focus and accessibility tree order to match, without requiring DOM reordering.
The examples below show reading-flow on a grid layout, a flex row with reversed visual order, a card grid where the visual order changes at a breakpoint, and how to apply it in a WordPress block theme for accessible reordered layouts.
/* ── 1. reading-flow: normal (default) vs grid-rows ──────────────────────
Without reading-flow, Tab key follows DOM source order.
reading-flow: grid-rows makes Tab follow grid row-by-row left-to-right. */
.grid-layout {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1rem;
reading-flow: grid-rows; /* Tab follows visual row order */
}
/* ── 2. Flex container: reversed visual order ────────────────────────────
Without reading-flow, Tab on a flex-direction:row-reverse container
moves right-to-left (DOM order), not left-to-right (visual order). */
.nav-reversed {
display: flex;
flex-direction: row-reverse;
reading-flow: flex-visual; /* Tab follows visual left-to-right order */
}
/* ── 3. Grid with named areas and responsive reordering ─────────────────── */
.page-layout {
display: grid;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
reading-flow: grid-order; /* follows grid-area / order properties */
}
@media (max-width: 768px) {
.page-layout {
grid-template-areas:
"header"
"main" /* main comes before sidebar on mobile */
"sidebar"
"footer";
/* reading-flow: grid-order still works — Tab now follows mobile visual order */
}
}
/* ── 4. WordPress block theme: accessible columns block ────────────────── */
.wp-block-columns {
reading-flow: flex-visual;
}
/* When columns are reversed via is-style-* modifier */
.wp-block-columns.is-style-reversed {
flex-direction: row-reverse;
reading-flow: flex-visual; /* Tab still goes left-to-right visually */
}
/* ── 5. Values summary ───────────────────────────────────────────────────
normal → default (DOM order)
flex-visual → follows visual flex order
flex-flow → follows flex-flow direction
grid-rows → left-to-right, row by row
grid-columns → top-to-bottom, column by column
grid-order → follows the CSS order property / grid-area placement */
NOTE: reading-flow only affects focus navigation order for keyboard users — it has no effect on DOM order (which screen readers may still follow depending on their reading mode); for full accessibility, pair reading-flow with correct semantic HTML and test with both keyboard navigation and a screen reader in document reading mode.