Close Menu
    DevStackTipsDevStackTips
    • Home
    • News & Updates
      1. Tech & Work
      2. View All

      Slack’s AI search now works across an organization’s entire knowledge base

      July 17, 2025

      In-House vs Outsourcing for React.js Development: Understand What Is Best for Your Enterprise

      July 17, 2025

      Tiny Screens, Big Impact: The Forgotten Art Of Developing Web Apps For Feature Phones

      July 16, 2025

      Kong AI Gateway 3.11 introduces new method for reducing token costs

      July 16, 2025

      Got ChatGPT Plus? You can record and summarize meetings on a Mac now – here’s how

      July 17, 2025

      I put this buzzworthy 2-in-1 robot vacuum to work in my house – here’s how it fared

      July 17, 2025

      AI agents will change work and society in internet-sized ways, says AWS VP

      July 17, 2025

      This slick gadget is like a Swiss Army Knife for my keys (and fully trackable)

      July 17, 2025
    • Development
      1. Algorithms & Data Structures
      2. Artificial Intelligence
      3. Back-End Development
      4. Databases
      5. Front-End Development
      6. Libraries & Frameworks
      7. Machine Learning
      8. Security
      9. Software Engineering
      10. Tools & IDEs
      11. Web Design
      12. Web Development
      13. Web Security
      14. Programming Languages
        • PHP
        • JavaScript
      Featured

      The details of TC39’s last meeting

      July 17, 2025
      Recent

      The details of TC39’s last meeting

      July 17, 2025

      Notes Android App Using SQLite

      July 17, 2025

      How to Get Security Patches for Legacy Unsupported Node.js Versions

      July 17, 2025
    • Operating Systems
      1. Windows
      2. Linux
      3. macOS
      Featured

      Microsoft says it won’t change Windows 11’s system tray design after users feedback

      July 17, 2025
      Recent

      Microsoft says it won’t change Windows 11’s system tray design after users feedback

      July 17, 2025

      How Rust’s Debut in the Linux Kernel is Shoring Up System Stability

      July 17, 2025

      Microsoft is on track to become the second $4 trillion company by market cap, following NVIDIA — and mass layoffs

      July 17, 2025
    • Learning Resources
      • Books
      • Cheatsheets
      • Tutorials & Guides
    Home»News & Updates»What We Know (So Far) About CSS Reading Order

    What We Know (So Far) About CSS Reading Order

    May 27, 2025

    The reading-flow and reading-order proposed CSS properties are designed to specify the source order of HTML elements in the DOM tree, or in simpler terms, how accessibility tools deduce the order of elements. You’d use them to make the focus order of focusable elements match the visual order, as outlined in the Web Content Accessibility Guidelines (WCAG 2.2).

    To get a better idea, let’s just dive in!

    (Oh, and make sure that you’re using Chrome 137 or higher.)

    reading-flow

    reading-flow determines the source order of HTML elements in a flex, grid, or block layout. Again, this is basically to help accessibility tools provide the correct focus order to users.

    The default value is normal (so, reading-flow: normal). Other valid values include:

    • flex-visual
    • flex-flow
    • grid-rows
    • grid-columns
    • grid-order
    • source-order

    Let’s start with the flex-visual value. Imagine a flex row with five links. Assuming that the reading direction is left-to-right (by the way, you can change the reading direction with the direction CSS property), that’d look something like this:

    CodePen Embed Fallback

    Now, if we apply flex-direction: row-reverse, the links are displayed 5-4-3-2-1. The problem though is that the focus order still starts from 1 (tab through them!), which is visually wrong for somebody that reads left-to-right.

    CodePen Embed Fallback

    But if we also apply reading-flow: flex-visual, the focus order also becomes 5-4-3-2-1, matching the visual order (which is an accessibility requirement!):

    <div>
      <a>1</a>
      <a>2</a>
      <a>3</a>
      <a>4</a>
      <a>5</a>
    </div>
    div {
      display: flex;
      flex-direction: row-reverse;
      reading-flow: flex-visual;
    }
    CodePen Embed Fallback

    To apply the default flex behavior, reading-flow: flex-flow is what you’re looking for. This is very akin to reading-flow: normal, except that the container remains a reading flow container, which is needed for reading-order (we’ll dive into this in a bit).

    For now, let’s take a look at the grid-y values. In the grid below, the grid items are all jumbled up, and so the focus order is all over the place.

    CodePen Embed Fallback

    We can fix this in two ways. One way is that reading-flow: grid-rows will, as you’d expect, establish a row-by-row focus order:

    <div>
      <a>1</a>
      <a>2</a>
      <a>3</a>
      <a>4</a>
      <a>5</a>
      <a>6</a>
      <a>7</a>
      <a>8</a>
      <a>9</a>
      <a>10</a>
      <a>11</a>
      <a>12</a>
    </div>
    div {
      display: grid;
      grid-template-columns: repeat(4, 1fr);
      grid-auto-rows: 100px;
      reading-flow: grid-rows;
      
      a:nth-child(2) {
        grid-row: 2 / 4;
        grid-column: 3;
      }
    
      a:nth-child(5) {
        grid-row: 1 / 3;
        grid-column: 1 / 3;
      }
    }
    CodePen Embed Fallback

    Or, reading-flow: grid-columns will establish a column-by-column focus order:

    CodePen Embed Fallback

    reading-flow: grid-order will give us the default grid behavior (i.e., the jumbled up version). This is also very akin to reading-flow: normal (except that, again, the container remains a reading flow container, which is needed for reading-order).

    There’s also reading-flow: source-order, which is for flex, grid, and block containers. It basically turns containers into reading flow containers, enabling us to use reading-order. To be frank, unless I’m missing something, this appears to make the flex-flow and grid-order values redundant?

    reading-order

    reading-order sort of does the same thing as reading-flow. The difference is that reading-order is for specific flex or grid items, or even elements in a simple block container. It works the same way as the order property, although I suppose we could also compare it to tabindex.

    Note: To use reading-order, the container must have the reading-flow property set to anything other than normal.

    I’ll demonstrate both reading-order and order at the same time. In the example below, we have another flex container where each flex item has the order property set to a different random number, making the order of the flex items random. Now, we’ve already established that we can use reading-flow to determine focus order regardless of visual order, but in the example below we’re using reading-order instead (in the exact same way as order):

    div {
      display: flex;
      reading-flow: source-order; /* Anything but normal */
    
      /* Features at the end because of the higher values */
      a:nth-child(1) {
        /* Visual order */
        order: 567;
        /* Focus order */
        reading-order: 567;
      }
    
      a:nth-child(2) {
        order: 456;
        reading-order: 456;
      }
    
      a:nth-child(3) {
        order: 345;
        reading-order: 345;
      }
    
      a:nth-child(4) {
        order: 234;
        reading-order: 234;
      }
    
      /* Features at the beginning because of the lower values */
      a:nth-child(5) {
        order: -123;
        reading-order: -123;
      }
    }
    CodePen Embed Fallback

    Yes, those are some rather odd numbers. I’ve done this to illustrate how the numbers don’t represent the position (e.g., order: 3 or reading-order: 3 doesn’t make it third in the order). Instead, elements with lower numbers are more towards the beginning of the order and elements with higher numbers are more towards the end. The default value is 0. Elements with the same value will be ordered by source order.

    In practical terms? Consider the following example:

    div {
      display: flex;
      reading-flow: source-order;
    
      a:nth-child(1) {
        order: 1;
        reading-order: 1;
      }
    
      a:nth-child(5) {
        order: -1;
        reading-order: -1;
      }
    }
    CodePen Embed Fallback

    Of the five flex items, the first one is the one with order: -1 because it has the lowest order value. The last one is the one with order: 1 because it has the highest order value. The ones with no declaration default to having order: 0 and are thus ordered in source order, but otherwise fit in-between the order: -1 and order: 1 flex items. And it’s the same concept for reading-order, which in the example above mirrors order.

    However, when reversing the direction of flex items, keep in mind that order and reading-order work a little differently. For example, reading-order: -1 would, as expected, and pull a flex item to the beginning of the focus order. Meanwhile, order: -1 would pull it to the end of the visual order because the visual order is reversed (so we’d need to use order: 1 instead, even if that doesn’t seem right!):

    div {
      display: flex;
      flex-direction: row-reverse;
      reading-flow: source-order;
    
      a:nth-child(5) {
        /* Because of row-reverse, this actually makes it first */
        order: 1;
        /* However, this behavior doesn’t apply to reading-order */
        reading-order: -1;
      }
    }
    CodePen Embed Fallback

    reading-order overrides reading-flow. If we, for example, apply reading-flow: flex-visual, reading-flow: grid-rows, or reading-flow: grid-columns (basically, any declaration that does in fact change the reading flow), reading-order overrides it. We could say that reading-order is applied after reading-flow.

    What if I don’t want to use flexbox or grid layout?

    Well, that obviously rules out all of the flex-y and grid-y reading-flow values; however, you can still set reading-flow: source-order on a block element and then manipulate the focus order with reading-order (as we did above).

    How does this relate to the tabindex HTML attribute?

    They’re not equivalent. Negative tabindex values make targets unfocusable and values other than 0 and -1 aren’t recommended, whereas a reading-order declaration can use any number as it’s only contextual to the reading flow container that contains it.

    For the sake of being complete though, I did test reading-order and tabindex together and reading-order appeared to override tabindex.

    Going forward, I’d only use tabindex (specifically, tabindex="-1") to prevent certain targets from being focusable (the disabled attribute will be more appropriate for some targets though), and then reading-order for everything else.

    Closing thoughts

    Being able to define reading order is useful, or at least it means that the order property can finally be used as intended. Up until now (or rather when all web browsers support reading-flow and reading-order, because they only work in Chrome 137+ at the moment), order hasn’t been useful because we haven’t been able to make the focus order match the visual order.


    What We Know (So Far) About CSS Reading Order originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

    Source: Read More 

    Facebook Twitter Reddit Email Copy Link
    Previous ArticleAnimated Product Grid Preview with GSAP & Clip-Path
    Next Article CVE-2025-5117 – WordPress Property Plugin Privilege Escalation Vulnerability

    Related Posts

    News & Updates

    Got ChatGPT Plus? You can record and summarize meetings on a Mac now – here’s how

    July 17, 2025
    News & Updates

    I put this buzzworthy 2-in-1 robot vacuum to work in my house – here’s how it fared

    July 17, 2025
    Leave A Reply Cancel Reply

    For security, use of Google's reCAPTCHA service is required which is subject to the Google Privacy Policy and Terms of Use.

    Continue Reading

    10 Top React.js Development Service Providers For Your Next Project In 2026

    Tech & Work

    Keep Your Place: Enhancing User Experience with Fragment Method

    Development

    File Shredder permanently deletes files

    Linux

    Windows Hello face unlock no longer works in the dark, and Microsoft says it’s not a bug

    News & Updates

    Highlights

    CVE-2025-6951 – SAFECAM X300 FTP Service Default Credentials Vulnerability

    July 1, 2025

    CVE ID : CVE-2025-6951

    Published : July 1, 2025, 12:15 p.m. | 3 hours, 20 minutes ago

    Description : A vulnerability classified as problematic was found in SAFECAM X300 up to 20250611. This vulnerability affects unknown code of the component FTP Service. The manipulation leads to use of default credentials. Access to the local network is required for this attack to succeed. The exploit has been disclosed to the public and may be used. The vendor was contacted early about this disclosure but did not respond in any way.

    Severity: 4.3 | MEDIUM

    Visit the link for more details, such as CVSS details, affected products, timeline, and more…

    CVE-2025-7474 – Job Diary SQL Injection Vulnerability

    July 12, 2025

    Critical Golden dMSA Attack in Windows Server 2025 Enables Cross-Domain Attacks and Persistent Access

    July 16, 2025

    CVE-2025-20693 – Intel Wireless LAN STA Driver Out-of-Bounds Read Information Disclosure Vulnerability

    July 8, 2025
    © DevStackTips 2025. All rights reserved.
    • Contact
    • Privacy Policy

    Type above and press Enter to search. Press Esc to cancel.