The aria-controls attribute is important for composite widgets where one element controls another, such as navigation widgets (links, buttons, or tabs controlling another section), tree views, and similar relationships where one element controls another. The attribute defines the relationship so that assistive technology users can navigate to the content effected by the controlling element; for example, from a tab to the associated tab panel.
Considering the importance of being able to define these relatively simple relationships, the
aria-controls attribute has surprisingly poor support. The only browser/assistive technology combination that I'm aware of that supports this relationship at the moment is Firefox/JAWS.
Author: Gez Lemon
Simple tab control design pattern
A simple tab control design pattern will illustrate this issue, and is fairly common in web applications.
As the tabs are a collection of links, they should initially be marked up in an unordered list, but the list roles should be overridden using WAI-ARIA roles and use properties to ensure they are understandable to assistive technologies. The unordered list (
ul) containing the list of links should have a role of tablist. The list items themselves could be put in to the keyboard tab order with the correct roles, or the list items could contain regular anchor elements that have their roles changed to make them understandable to screen readers. If this approach is chosen, the role of the list items should be changed to presentation so the semantics of list items are not conveyed to assistive technologies. The rest of this discussion assumes an anchor element will be used within a list item, as that's the best approach for progressive enhancement and seems to be the most common design pattern deployed for tabs.
Each anchor element in the list should have a role of tab, and the following attributes should be set for each anchor element:
- aria-selected - indicates whether this tab is the currently selected tab in the tab list.
- aria-controls - identifies the id attribute value of the panel that is displayed when this tab is selected. This is the relationship that should allow assistive technologies to navigate to the panel.
- tabindex - A value of
0means that the element is included in the tab order where it is in the source, and a value of
objTab.focus();). Only the currently selected item in the tab should have a tabindex attribute value of 0, so the user can skip the group of links pressing TAB. Using the cursor keys should change the TAB selection (the keyboard keystrokes provided at the end of this section).
The panels that are controlled by the tabs in the tab list should have a role of tabpanel, and the following attributes should be set on each panel:
- aria-hidden - Indicates whether the element is visible or not.
- aria-expanded - Indicates whether the element is currently expanded or collapsed.
- aria-labelledby - Identifies the tab that labels this panel.
Consider the following example with 4 tabs.
The following is the markup to produce the 4 tabs so they are exposed correctly to assistive technologies using the design pattern outlined above. In this example, the second tab, "Review Terms", is the currently selected tab.
The following keystrokes should be supported by the tab control.
|TAB||The active tab in the tab list should initially receive focus. Pressing TAB again should move focus to the next focusable element outside of the tab list, which might be in the associated tab panel.|
|LEFT ARROW||When focus is on a tab in the tab list, focus should move to the previous tab in the list. When the first tab in the list has focus and the LEFT ARROW is pressed, the last tab in the tab list should receive focus.|
|RIGHT ARROW||When focus is on a tab in the tab list, focus should move to the next tab in the list. When the last tab in the list has focus and the RIGHT ARROW is pressed, the first tab in the tab list should receive focus.|
|UP ARROW||When focus is on a tab in the tab list, focus should move to the previous tab in the list. When the first tab in the list has focus and the UP ARROW is pressed, the last tab in the tab list should receive focus.|
|DOWN ARROW||When focus is on a tab in the tab list, focus should move to the next tab in the list. When the last tab in the list has focus and the DOWN ARROW is pressed, the first tab in the tab list should receive focus.|
There must be a way for assistive technology users to navigate from the tabs to the tab panels. Cursor keys are usually used as reading keys, but the cursor keys are being used to control the tabs so are no longer available for this purpose. This is where the
aria-controls attribute should help, as the relationship is defined, so there just needs to be a way for the user to navigate to the associated panel.
Firefox with JAWS does this by announcing, "Press JAWS key + ALT + M to move to controlled element". When those keys are pressed, JAWS announces, "Moved to controlled element". The user can then navigate the panel using regular keystrokes. Unfortunately, all other browser/assistive technology combinations I tried did not provide a mechanism to navigate to the controlled element. Chrome/JAWS consistently announces, "Failed to move to controlled element" when using JAWS key + ALT + M, so it could be they plan to implement something soon with JAWS.
There are obviously ways of navigating into the panel, but not acceptable equivalents of certainly knowing that you're at the top of the panel. For example, in JAWS, a user could toggle the virtual cursor on and off to break the cursor navigation with tabs and then navigate to the panel. Or the user could tab to the next focusable interface element (if there is one, which may or may not be in the tab panel), and then navigate backwards to try and find the tab. But these are clumsy recovery techniques that users will have to use if these kinds of widgets are deployed without user agent support. The only solution I can think of now is for developers to designate a keystroke that allows navigation to the panel, and ensure it's documented, until there is better support.