FE / CSS / a11y / TIL

Accessibility issues using order in grid and flex

I was recently involved in an accessibility audit when I came across a similar situation described by “Flex order property, screen readers and accessibility”.

To my great surprise, I learned another interesting way we can break accessibility with css (among others) - that is by using the order property.

The accessibility issue

Grid and flex let you reorder elements very easily, but just visually.
Which means that within the DOM your html elements are still in the original position.

This means that when you tab around if you have any link or focusable element within one of the elements you reordered, you may find yourself jumping all around the page.

And that is not good my friend!
Jumping around, especially with screen readers can be quite confusing.

The worst part for me was that in a way is kind of broken by design.

So, how should you fix similar issues?

Note: In my case, we had one layout on mobile and one on desktop. One particular element was getting moved from the end to the bottom.

If it’s basic html order, and you don’t need any fancy UI jumping on strange screen resolution, then update the html if you can (why did you use order at all in this case? Really, I would love to know the scenario and constraints).

Else chat with your designer and ask for a different design, possibly that won’t impose accessibility issues.

If you really have to maintain that layout, then probably you got two options:

  • duplicate the html and show hide using media queries
  • use js to manipulate the DOM

Focusable elements out of the box:

  • inputs
  • buttons
  • a with valid href

within the accessibility tree they have a focusable attribute.

Notes: a11y := a(ccessibilit)y. 11 is the length of ccessibilit

Duplicate the html and show hide using media queries

With Tailwind would look like:

<div class="block md:hidden">
    ... links mobile here
</div>
.
.
.
<div class="hidden md:block">
    ... links desk here
</div>

With Bootstrap would look like:

<div class="d-block d-md-none">
    ... links mobile here
</div>
.
.
.
<div class="d-none d-md-block">
    ... links desk here
</div>

Use js to manipulate the DOM

function onResize() {
    if (window.innerWidth < 600) {
        // do mobile things
    }
    .
    .
    .
}

// trigger on resize
window.addEventListener('resize', onResize);

// trigger on load
onResize(); 

For a11y testing you can use:

In summary

The order property is basically doomed for accessibility.
If you can, compromise on design if that imposes strange constraints.
Else code duplication or js may be your only workaround.