Aria-Controls is Poop

We need to talk about aria-controls. It’s poorly supported, does very little, and does what it does when it does badly. It is poop and we rely on it way too much. We are short-changing assistive technology users when we do.

What it is

The aria-controls attribute is a ‘relationship attribute’ which denotes which elements in a page an interactive element or set of elements has control over and affects. It’s commonly used to describe a relationship between a button and the expandable region revealed by that button.

<button aria-expanded="false" aria-controls="expandable">open / close</button>
<div id="expandable" hidden>content of the expandable region</div>

What we think it does

Wishfully thinking, we assume that marking up relationships with aria-controls means screen reader users can effortlessly flit between the moving parts of a web application, like a mechanic tinkering in a ship’s engine room.

Because we’ve used aria-controls, we don’t have to worry about source order, right? We’ve connected up the dots explicitly, with our magic attribute! And it doesn’t matter about all the elements between a controller and its subject because we’ve tunneled between them, right?

<button aria-expanded="false" aria-controls="expandable">open / close</button>
  <!-- a load of other markup, including interactive elements in focus order -->
<div id="expandable" hidden>content of the expandable region</div>

Good luck with that

First of all, only the JAWS screen reader supports aria-controls. If a user is operating NVDA or VoiceOver (or others), they would have no idea it’s even there. That’s reason enough not to use it.

But, just for giggles, let’s talk about how JAWS supports aria-controls. When you focus an element with the attribute included, JAWS will announce, “press the JAWS key plus Alt and M to move to the controlled element.” Verbose and clumsy. Then again, I’m not sure how else you’d go about supporting it.

But, that’s not the only problem. How in the hell do I move back? And, even if I could, how would that be communicated and how long should the option to move back remain active? No wonder the other screen reader vendors are giving this a wide berth.

Multiple controlled elements

You can create a one-to-many relationship by supplying a space separated list of ids, representing different, simultaneously controlled elements.

<button aria-controls="elem1 elem2 elem3 elem4">open / close</button>

Cute! And good luck with implementing a half-decent UX there, everybody. In case you’re interested, JAWS just says “press the JAWS key plus Alt and M to move to the controlled element” as normal. Genius.


The aria-controls attribute is a prime example of something we’d love to ‘just work’. Trouble is, there’s no clear way how it should work. JAWS makes a perfunctory attempt at implementation, but it’s incomplete and I suspect it creates much more confusion than it provides clarity for real users.

In the absence of a good purpose-built solution for letting folks using an interface aurally move between and around tools and their outputs, try a combination of the following:

  • Same-page links to move users from one part of the interface to another
  • Landmark roles to encapsulate major areas of the interface’s functionality
  • Expandable areas that come immediately after their aria-expanded controllers in the source (and in focus order)

There’s also the question of ‘focus management’. In keyboard and screen reader accessibility terms, focus management usually means using the focus() method in JavaScript to move focus between elements. Be aware that, in almost all cases, users do not want to be moved from one place to another without their explicit say-so. Even when they do want to, providing a link is probably your best bet.

I think I’ll give the focus management wasps’ nest a proper poke on another occasion.