Accessibility Inspectors: A Basic Guide

As accessibility-minded developers working on accessibility-minded teams, we strive to design and build inclusive applications that yield a pleasant experience for all users. However, despite our best efforts we may make mistakes and implement features in a sub-optimal way, or worse, discover that some users cannot use those features at all. Fortunately, in recent years browsers have introduced tools that help debug some of these issues. Here we will focus on the built-in accessibility inspectors that allow developers to navigate the accessibility tree that browsers present to assistive technologies.

Accessibility Tree

While most of the DOM tree will exist in some form in the accessibility tree, the browser can optimize the accessibility tree by removing hidden elements or those it determines provide no useful meaning to the user (e.g., presentation-only wrapper nodes). Further, the exact structure of the accessibility tree is implementation-specific; for example, browsers may use different node names for identical nodes, decorate nodes with properties not used by other browsers, or attempt to correct poorly-constructed markup. However, there are commonalities that are required for compatibility with the underlying accessibility API, including an element’s:

  • role, which helps inform users how they can expect to interact with the element. For example, if an element’s role is listed as “checkbox” or “checkbutton” (depending on the browser), the user knows the element can receive focus and get selected or deselected.
  • optional name or label, which helps define the purpose of the element. For example, if the element is a button, its text content will get used as its name. Alternatively, if it contains an aria-label attribute, its name will be the value of that attribute; if it contains an aria-labelledby attribute, then its name will be the computed name of the element with the ID specified by aria-labelledby.
  • various states, such as whether the element is focusable, disabled, selected, etc.

Accessibility Inspectors

In the following sections, we will examine each availability inspector in turn using an example breadcrumb implementation using the HTML below. Note that no styling has been applied and that the list HTML is deliberately malformed in order to demonstrate how it affects the accessibility tree in each browser:

Firefox

In order to optimize performance, browsers will not generate an accessibility tree unless needed. So once the “Accessibility” tab is enabled and displayed, the accessibility features need to be enabled via the “Turn On Accessibility Features” button unless an assistive technology is already running. With the accessibility features enabled, the accessibility tree is displayed in the tab contents, and the accessibility properties of any node get revealed by 1) expanding nodes in the tree individually, 2) using the “Pick accessible object from the page” button (the first button in the toolbar when the “Accessibility” tab is selected) or 3) right-clicking any element on the page and choosing “Inspect Accessibility Properties” from the context menu.

Returning to breadcrumb example above, Firefox generates the following accessibility tree:

Even with our small example, there is much to explore. The main tab content area displays each node’s role and name, but there is also a “Properties” accordion pane that contains additional information such as the node’s various states (e.g., “focusable” and “enabled”). In order to understand how this helps us improve the user experience, notice that the structure of the breadcrumb list appears wrong. Specifically, after the list node we would expect there to be listitem nodes for each of the three items in the breadcrumb. Instead, there is a single section followed by three text container nodes. This is due to the <div> that wraps the three <li> tags, and the resulting accessibility tree structure indicates that assistive technologies may not present this to users in the way we expect. In fact, VoiceOver on macOS does not treat this example as a list of three items, but instead as a list of one item, so that navigating through the list results in the following reading:

list one item
link, Step One
link, Step Two
link, Step Three

To correct this, we need to remove the <div> around the three list items in order to restore the expected relationship between the list and its individual items:

After removing the <div>, the accessibility tree displays the breadcrumb items as listitem nodes as expected, and VoiceOver now indicates that our list has three items, and also reads each step number:

list three items
text, 1 of 3
link, Step One
text, 2 of 3
link, Step Two
text, 3 of 3
link, Step Three

Chrome and Chromium Browsers

In the above image, the <div> that wraps the breadcrumb's list items is selected and its accessibility properties get displayed. In Firefox, this node was included in the accessibility tree, degrading the user experience. However, the "Computed Properties" for this same node in Chrome report, "Accessibility node not exposed. Element not interesting for accessibility." If we then highlight one of the links in the breadcrumb, we can see in the "Accessibility Tree" accordion pane that the relationship between the list and the list item is preserved. Chrome recognizes that the <div> should not have been added around the list items and therefore ignores it.

Of course, we cannot be certain what an AT will read to users until we test it ourselves. Navigating our page with VoiceOver enabled verifies that we interpreted the computed accessibility correctly:

list 3 items
1
link, Step One
2
link, Step Two
3
link, Step Three

Note that this simple example was chosen deliberately to demonstrate how browsers might modify the DOM tree when generating the accessibility tree. Since there is no guarantee that such behavior will be preserved in future releases or that all poorly-written markup will be optimized, we still must fix our code. After doing so, VoiceOver verifies that everything is read as expected:

list 3 items
1
link, Step One
2
link, Step Two
3
link, Step Three

Safari

Safari’s inspector reports only a small number of properties for each node: its role, name (which it calls “label”), parent, children, ARIA properties, and basic states such as whether the node is disabled or focused. As is shown by the previous image, the accessibility properties for the <div> that wraps the list items include “Ignored: Yes”, indicating that Safari, like Chrome, has “fixed” the accessibility tree for AT users for this specific example. Before correcting our markup, we can prove this by listening to how VoiceOver reads our page (note that Safari also supports the aria-current attribute added to the second breadcrumb item):

list 3 items
1
link, Step One
2
current step, link, Step Two
3
link, Step Three

Conclusion

Do you need help improving the accessibility of your applications? Contact us to discuss how we can help you improve your applications and provide excellent experiences for all users.

Originally published at https://www.sitepen.com on May 6, 2020.

Modernizing Apps, Tools & Teams | sitepen.com | Twitter: @sitepen