Short note on progressive ARIA

When we talk about Progressive Enhancement (PE), we usually focus on HTML, CSS, and JavaScript, and often forget about ARIA. But when ARIA is hard-coded into HTML it can have unintended consequences if/when the JavaScript fails to deliver the expected functionality.

We use ARIA to provide or change the semantic information for HTML elements. This is almost always done to make an interactive component more accessible to screen reader users, and more often than not that interactivity is dependent on Javascript.

An example is a link that has been repurposed to be a button. Ignoring the fact this is a lousy design pattern to use in the first place, it’s surprisingly common out in the wild.

<a href="#disclosure" class="button" role="button">Additional information</a>

There is an important difference between a link and a button: a link can be activated using the enter key, and a button can be activated using the enter or space key. When you repurpose a link to be a button, the additional keyboard support must be provided using JavaScript.

If the button role is hard-coded into the HTML, and the JavaScript fails for any reason, a screen reader user is left with the impression that they’re dealing with a button, but if they use the space key to activate it, nothing will happen.

Another example is a static table that has sortable functionality added using JavaScript. We use various ARIA attributes to inform screen reader users about the role and state of the controls that allow the table data to be sorted, and provide the sort functionality using JavaScript.

<th aria-sort="none"><span role="button" tabindex="0">First name</span></th>
<th aria-sort="none"><span role="button" tabindex="0">Last name</span></th>

As before, if the ARIA is hard-coded and the JavaScript fails, a screen reader user is left with the impression that they’re dealing with a sortable table that is broken. They will think there are buttons at the top of each column and that data is currently sorted in a particular order, yet when they try to sort the table, nothing will happen.

It’s worth mentioning at this point, that accessibility is no longer a common reason for JavaScript to be unavailable. It used to be that Assistive Technologies (AT) like screen readers struggled to cope with JavaScript, and so AT users chose to disable it by choice. The 2009 WebAIM Screen Reader Users survey found that 10% of people disabled JavaScript in their browser, but by the 2014 Screen Reader users survey (the last time the question was included), the number had fallen to just 2%.

The fact is that everyone is vulnerable to JavaScript failing. As Ian Feather of Buzzfeed noted in his DeltaV talk on Frontend Resilience, 1% of JavaScript requests to the Buzzfeed website fail every month. That’s 13 million requests (a greater proportion of page views than IE11). JavaScript fails for all of us at some point or another, for many different reasons, and Stuart Langridge’s Everyone has JavaScript, Right? explains many of those reasons.

The W3C Note on Using ARIA has more detail, but it comes down to this: if you use JavaScript to provide functionality and/or any form of interaction, then the ARIA should be applied progressively (using JavaScript) too. In other words, let the accessibility degrade as gracefully as the rest of your code.

Categories: Development


Bill says:

What about youtube links that are converted to a more button-like action with javascript, presenting the video on-page?

something like

Does this require any additional info for screenreaders?

Bill, the demo page shows that each link is a normal link to YouTube. JavaScript comes along and traps those links to launch modals instead. The images lack useful alt text, so there is little clue to a screen reader user where the link goes, and the modals themselves do not manage focus nor announce themselves correctly. If the JavaScript is disabled, those linked images just need better alt text. With JavaScript enabled, the author of that script would benefit from reading The current state of modal dialog accessibility to fix the modals.

Mattia says:

You should not use span with button role and force focus with tabindex… just use the appropriate html tag, button.

Mattia, the point of the post was to show that when the wrong element is used or a complex widget is created, adding those roles and properties should be done in a PE way. As evidence, see where she calls the approach of using the wrong element a “lousy design pattern”. That being said, a button in the table sort column needs JS to do anything, so building it in a PE way means that maybe a span is appropriate since without JS the button would do nothing and appear broken. If you do have control over the HTML, then you can use a disabled attribute on the button and remove it with JS.