How do you know when to use ARIA and when it isn’t necessary? What do roles do to native HTML semantics? Are there additional requirements for working with ARIA? All these questions are easily answer if you understand the five rules for using ARIA in HTML.
The last few weeks, I’ve been talking about WAI-ARIA. After an introduction and example I walked you through the roles model, including both roles and their supported states and properties.
Today I want to take a step back and focus on another document with advice for using ARIA in HTML. I want to look at the the guidelines provided by the document and consider them something of a summary for this series.
Five Rules For Using ARIA In HTML
As you’ve seen through this series, a significant part of working with ARIA is in the details. Those details are too numerous to try and present here so I’ve instead focused on helping you understand how everything is organized so you can find what you need quicker and easier.
Keeping with the same goal, I want to present some general guidelines for using ARIA in HTML. I’ve mentioned a couple of them in passing, though without much explanation. The W3C refers to them as rules, but I’m not a big fan of absolute rules and I’ll bounce back and forth between calling them rules and guidelines.
Here are all five. I’ve rewritten the first one in this list, since I think the full rule is a bit more confusing. The full rule starts the next section.
- If you can use native HTML elements and attributes to communicate the proper semantics and behavior then do so.
- Don’t change native semantics, unless you really have to.
- All interactive ARIA controls must be usable with the keyboard.
- Don’t use role=“presentation” or aria-hidden=“true” on a visible focusable element.
- All interactive elements must have an accessible name.
First Rule of ARIA Use
If you can use a native HTML element or attribute with the semantics and behavior you require already built in, instead of re-purposing an element and adding an ARIA role, state or property to make it accessible, then do so.
The idea is to opt for writing semantically correct HTML and make use of HTML native semantics before reaching for ARIA.
If the semantics are already included in HTML then the additional ARIA isn’t necessary and you should just use the HTML. Adding ARIA support where it’s not needed is redundant code that isn’t doing anything. For the most part it won’t lead to problems, but it is a waste of time.
For example if you’re creating a button, then use the HTML button element. However, if for some reason you can’t and the button needs to be a div, go ahead and add ARIA semantics to communicate your div should be treated as a button.
You may remember earlier in the year I took a look at some of the new HTML5 structural elements. They map to ARIA roles, but not all browsers support the mapping yet so you would still add roles as in:
Again support for mapping some HTML5 elements to ARIA isn’t always there and you’re better off adding the redundancy and include the ARIA for the moment.
On the other hand most every element from HTML 4 and earlier is already mapped and doesn’t require additional ARIA. Writing semantically correct HTML is a huge step in writing documents that comply with ARIA standards.
Still there are some ARIA roles, states, and properties that are not available as features in HTML. You can find a list of them here. If you want to use any of these roles, you’ll need to add them to your HTML as they aren’t native to any element.
You might also be interested in this table of HTML elements and the ARIA roles, states, and properties which may be used on each element.
Second Rule of ARIA Use
Do not change native semantics, unless you really have to.
When you add an ARIA role to an HTML element, the semantics of the role override the semantics of the element as far as assistive devices are concerned.
Ideally you’ll follow the first rule and choose HTML elements that communicate the proper semantics, but sometimes you can’t. The Using ARIA document offers an example where you want to develop a heading as a button. One option is to use an h1 and add a button role.
<h1 role="button">heading button</h1>
The ARIA button semantics would override the semantics of the h1, which isn’t something you should generally do. Much like the DOM tree, there’s an accessibility tree. The code above would become a button in the accessibility tree and not a level 1 heading.
The change only affects assistive devices. The element will still look and behave as an h1 for everyone not using an assistive device.
The change also does’t add new states and properties. They would need to be added separately. The change only overrides the native role semantics.
A better option would be to use a button element and wrap it inside an h1.
The button element already carries the correct semantics for assistive devices so no ARIA role is needed. The h1 still carries its expected semantics as well. A possible third option if you can’t use a button element for some reason might be to use a span and give it the button role.
<h1><span role=button>heading button</span></h1>
Once again the h1 semantics aren’t overridden and a span is a generic container that can be given the semantics of a button using the ARIA role.
In general choose the best semantic elements and structure and don’t override the semantics of the HTML without good reason.
Third Rule of ARIA Use
All interactive ARIA controls must be usable with the keyboard.
This one is straightforward. Any widget you create that can be interacted with through mouse clicks, taps, drag and drop, sliding, scrolling, or whatever should be available through an equivalent keyboard action.
For example buttons should be able to receive focus, likely by tabbing through the elements on the page. Once it has focus hitting the Enter or Return key should be enough to activate the button action.
Fourth Rule of ARIA Use
Do not use role=“presentation” or aria-hidden=“true” on a visible focusable element.
Rule four is the most specific rule as it deals with two specific roles. The idea is that using either on a visible and focusable element will result in some users focusing on nothing.
Adding the presentation role to an element removes the semantics of the element and tells assistive devices the element is for presentation only.
<div role="presentation">Some text</div>
in the accessibility tree, which probably isn’t what you want.
Elements that don’t require children, like an h1, won’t remove the semantics of their child elements, but with elements that require children such as ordered and unordered lists, the children would also have their semantics removed.
Similarly, hiding an element for screen readers with the aria-hidden state when it’s accessible to non-assistive devices is not something you should generally do, however if the element is also visibly hidden and can’t be interacted with it’s ok to set aria-hidden to true.
Fifth Rule of ARIA Use
All interactive elements must have an accessible name.
For an interactive element to have an accessible name its Accessibility API accessible name property (or equivalent) needs a value. That’s a mouthful, but it’s not as confusing as it might sound. For example:
name <input type="text">
<label>name</label> <input type="text">
In both lines of code there’s a visible label of name for the input, but there’s no accessible name. You might ask about the second line with the label, but nothing connects the label to the input.
The code is better written as either of the following:
<label>name <input type="text"></label>
<label for="name">name</label> <input type="text" id="name">
Here both visible and accessible labels are included. The first line wraps the input inside the label and the second includes for and id attributes to make clear that the label applies to the input.
Ideally you’ll always use the most appropriate HTML elements and structures to convey semantic meaning to assertive devices, but sometimes you can’t. Ideally every ARIA role, property, and state would be communicated through HTML alone, but unfortunately some aren’t.
ARIA is markup that allows us to communicate important semantics when the native HTML can’t. ARIA allows you to define the role of an element or component in the interface, the properties of that component, and their current state.
It doesn’t add semantics to HTML. It overrides the native semantics on HTML so be careful that you’re adding it appropriately. Follow the five rules for adding ARIA to HTML and you should be ok.
That wraps up this series on accessibility and ARIA. I hoped it helped clear up any confusion you may have had. Later in the year I’ll revisit the topic, especially as I promised to fix things on this site to make it more accessible to more people.
Download a free sample from my book, Design Fundamentals.
If I want to make an input box that has no visible label accessible, by Rule 1, I should add the HTML tag Label for input box BEFORE just adding aria-label=”Label for input box” to the tag? Seems like that adds more code than is needed….
The point isn’t about which way is more code. it’s about semantics. Also keep in mind ARIA isn’t supported by all assisted technologies. The label tag is supported.