Beyond the scope of HTML
To get a more detailed overview of how the quality of our markup impacts end users, see my previous post How accessibility trees inform assistive tech. To summarise: our markup gets used to construct accessibility trees, which inform assistive technologies (AT) about what things are on our pages. With this information, AT can offer features like ‘browse by heading’ and advanced table navigation.
There are plenty of semantic elements to choose from when we build a component. The set of HTML elements is enormous. Even if you build a new thing for which no semantic element exists, custom components that combine existing HTML elements let you have at least some of your semantics for free.
Sometimes the set of HTML elements really does not cut it. You’ve created an interface concept for which reasonably no semantic tag exists in HTML. This is where WAI-ARIA comes in: it lets you provide accessibility-relevant information to the browser using standardised attributes, including semantics, states and labels.
Some examples of effective ARIA:
aria-expanded="true|false", you can set the state of a button that expands/collapses content
role="alert"you can turn an element into a live region: when content is updated, the update is announced to AT users
There is also ARIA that can turn elements into elements for which there are already existing HTML equivalents, such as buttons and links. This is not recommended, because apart from changing semantics, it also makes affordances like keyboard behavior the developer’s responsibility. For instance, instead of
<span role="button">, it is much safer to use
<button type="button"> and get the keyboard behaviour for free. In 2019, styling native buttons is no longer a problem. Certainly not one that warrants accessibility bugs like reduced keyboard support.
How AOM will help
So, let’s say you are making something that passes the first rule of ARIA (paraphrased: “don’t use ARIA if it is not needed”). You could use markup for this: just add the appropriate attributes. Once the Accessibility Object Model is implemented, you could also apply ARIA without markup.
Having access to low-level features like these, gives developers power (yay!). But at the same time, they also give developers more direct responsibility, regarding aspects like security, performance and accessibility. It can be tricky and time-consuming to implement best practices and fulfill all those responsibilities. Admittedly, is it easier, and often sensible, to use browser defaults. Extending the web like this is probably most practical for teams that are able to invest the time.
AOM is currently developed by people from across Mozilla, Google and Apple. They’ve defined four phases for the project. Let’s look at some of the plans and how they help.
No more ‘sprouting’
Interfaces with a lot of advanced controls can quickly become a sea of attributes, which the HTML spec calls “sprouting”. Even a simple disabled button might require
For example, to set
aria-expanded on an element, you could do it on the element directly:
el.ariaExpanded = true;
Previously, we could only set this attribute to expanded by switching the value of the attribute in the markup. With AOM, the set of ARIA attributes will also exist as properties that DOM nodes can have, so called IDL (Interface Definition Language) attributes. The IDL attributes are said to reflect attributes in the markup. In the above example, that means that upon setting
el.ariaExpanded to true, an attribute (if it does not yet exist) is added to
el and it is set to
The mapping of ARIA attributes to IDL attributes is defined in the ARIA 1.2 specification.
Note that in applications that have some form of virtual DOM, like those built with frameworks including React and Vue, best practices prescribe “don’t touch the DOM, let the framework deal with DOM changes”. In those applications, defining semantics in the markup or a template will probably still be the go-to approach.
Relationships without IDs
In HTML, the
id attribute uniquely identifies an element. Form labels make use of this: we associate
label attributes with their corresponding input by pointing the
for to the
id. In ARIA, there are a number of properties that need to point to an
id (or multiple
aria-controls (this element controls that element) and
aria-describedby (this element is described by this element/these elements).
With AOM, one can associate elements with other elements directly, by assigning them like this:
formField.ariaLabelledBy = formLabel;
Non-DOM nodes in the accessibility tree
In some very specific cases, a web application may contain content that does not exist as DOM nodes. For instance: drawing a train station’s map of available elevators on a
canvas. Each elevator has a label, and also a informational popup that can be expanded. This information would currently be lost to assistive technologies. With AOM, you could define an accessibility tree containing all the labels and expanded states. These would then be conveyed to AT, so that users can understand them.
Good for testing
The AOM also aims to bring reading accessibility attributes. The intended use case: testing! With AOM, you would be able to access the names, roles and states of your HTML nodes directly in tests.
Tests can already access an element’s ARIA information by reading out attributes today. With AOM, they would read out what something has actually computed to in the browser’s accessibility tree. This functionality has the potential to make tests better.
In her talk Web Components and the AOM at JSConf Asia 2019, Léonie Watson explained that actions like “swipe up” and “swipe down” mean different things to users of VoiceOver on iOS:
When you have a screenreader running on a touch screen, the flick up and flick down gestures [developers] would probably use for adjusting the value of a slider, are already used for screenreader specific commands.
Because screenreader users already use “swipe up” and “swipe down” gestures to trigger screenreader specific commands, it would be impossible for them to use the same gestures for something else in the app you’re developing.
This is why AOM aims to bring events that are specific to assistive technologies, so that AT can design consistent ways to let the user perform certain actions. Apple calls these semantic events.
Some examples of accessibility events:
decrementfor going to the next item in a custom slider (like using up and down arrow keys)
dismissfor closing a modal overlay (like pressing
There is a large privacy concern associated with AT-specific events: malicious site owners could use them to detect if someone has a visual or mobility impairment.
The specifications for AOM are still in progress, and so are implementations. Various browsers have implemented (parts of) AOM). The part that seems to have most implementations is attribute reflection. This feature works for most attributes in Chrome and Edge (enable via
about:config) and Safari (pick ‘Accessibility Object Model’ from Experimental Features setting in Developer menu). There is currently no AOM support not in Firefox.
If you look at the IDL tests with AOM flags enabled, you can see how much your browser supports of the attribute reflection part of the specification.
Simple solutions are often the easiest way to get your product to work for as many people as possible. For example, when for a date of birth field, you decide against a fancy, complex datepicker and rely on a clearly labelled
input[type=text] instead. Standard, boring HTML goes a long way. Chances are it will work well for users and make your accessibility auditors happy. But if your product has custom controls that just don’t exist in HTML, you will want to convey the right accessibility properties to assistive technologies.
AOM is an interesting new proposal in which accessibility information gets its own APIs beyond existing DOM methods like
getAttribute. Those methods set and get out values that compute into properties of accessibility trees, but they don’t deal with those properties directly. It’s a subtle difference. With direct access to accessibility info, we could set accessibility properties without markup, we could create accessibility trees for things that don’t exist in the DOM (like for contents of
canvas elements) and testing accessibility may improve.