Understanding Aria
When working on complex UIs or dynamic JavaScript-updated content, there are times when you cannot achieve your goal using semantic HTML. This is where ARIA plays an important role. It supplements HTML and passes interactions in applications to assistive technologies. For instance, when working with modals and custom elements, there is no semantic element you can use to announce its function to assistive technologies. WAI-ARIA bridges these accessibility issues that cannot be handled with native HTML.
In this article, I will explore the areas you need to use ARIA to augment the standard DOM accessibility tree.
Web Accessibility Initiative Accessible Rich Internet Applications (WAI-ARIA) is a specification written by the W3C. It defines a set of attributes that provide ways to make web content and web applications more accessible.
This does not mean that you should add roles and aria-* everywhere, it is preferable to write semantic HTML where possible, instead of using aria attributes. Semantic HTML can function effectively because they have the implicit meaning of these ARIA roles you declare explicitly; they have built-in keyboard accessibility, roles and states.
Instead of creating a custom checkbox and adding ARIA role and attributes to specify its function,
<span role="checkbox"
aria-checked="false"
aria-label="Not checked"
aria-labelledby="label"
name="checkbox"
tabindex="0"></div>
<span id="label">Custom checkbox</span>
use the actual HTML element
<input type="checkbox" aria-labelledby="label" name="checkbox">
<span id="label">Default checkbox</span>
Avoid using a <button>
where <a>
can suffice vice-versa. Instead of using
<a role="button">Place Order</a>
use
<button>
Place Order
</button>
While <a>
can be styled to look like a button, assistive technologies will have no clue and announce it as a link. <a>
implies that when clicked on, it will navigate the user to another page. However, <button>
is expected to trigger an action within the same page. Using the wrong elements makes visually impaired users miss out on the purpose of the element.
Features of WAI-ARIA
WAI-ARIA has three main features namely roles, properties, and states.
Roles define what an element is
<nav role="navigation">...</nav>
properties define attributes of elements which provide extra meaning to the element
<div aria-label="This is for screen readers">...</div>
and states define the current conditions of elements.
<label for="email">Email</label>
<input type="email" id="email" aria-disabled="true" />
Applications of WAI-ARIA
WAI-ARIA is applied in several use cases:
Landmarks
It is imperative to note that you do not have to redefine default semantics. ARIA role
replicate the default semantics of HTML5 elements. Adding role to a semantic element is a duplication as they have implicit ARIA semantics. However, if you are working on complex UI, or developing for old browsers e.g. IE8, adding the role attribute is essential.
The search form is an important landmark that people will want to find, but it is not treated as one; it is read to screen readers as edit text. To treat it as a notable landmark, add the role attribute.
Try navigating to these two search fields using a keyboard and listen to what is read out by the screen reader to notice the difference.
<!-- anti-pattern but useful for old browsers e.g. IE8 -->
<main role="main">...</main>
<!-- standard -->
<main>...</main>
<input
type="search"
role="search"
placeholder="Search..."
aria-label="Search for products, brands and categories..."
/>
Announcing Updates
Dynamic contents are not reported to screen readers by default. Use aria-live
to report these updates. While aria-live="polite"
informs the user about a particular change when they are idle, aria-live="assertive"
intercepts whatever they are doing and announces the update.
<input
type="search"
role="search"
placeholder="Search..."
aria-label="Search for products, brands and categories..."
/>
<ul aria-live="polite" id="search_results">
<li>item 1</li>
<li>item 2</li>
</ul>
However, only the updated part is read out. You can use aria-atomic="true"
to control the area of the live region to be read out. When it is set to false, only the updated area will be read out. aria-busy="true"
forces screen readers to wait till all updates are complete before reading the update.
<div aria-live="polite" aria-atomic="true" aria-busy="true">
<span>Total: $400</span>
</div>
Bridging Accessibility Gap
When creating complex UIs that cannot be achieved with native HTML elements, use ARIA attributes to bridge the gap. WAI-ARIA extends the tabindex attribute to make non-focusable elements focusable.
tabindex="0"
provides tabbable functionality to elements that are not tabbable.
tabindex="-1"
allows non-tabbable elements to receive focus programmatically using JavaScript or as the target for links.
<nav>
<ul>
<li>
<a href="#about">
About
</a>
</li>
</ul>
</nav>
<section id="about" tabindex="-1">
About Us
</section>
Error Alerting
You can use ARIA roles and attributes like alert
and aria-relevant
for alerting users about errors. The aria-relevant
attribute is used to control what gets read out when a live region is updated i.e. content additions or removals.
<div class="errors" role="alert" aria-relevant="all">...</div>
Form Handling
There are different aria attributes used for form handling. You can use aria-disabled attribute to define the current state of elements on web applications. aria-disabled="true"
tells a screen reader that the form input in focus is disabled.
aria-required="true"
should be used on required form input to specify that the input needs to be filled in and aria-invalid="true"
is used to specify invalid form entries.
<label for="email">Email</label>
<input id="email" type="email" aria-required="true"/>
Form Labelling
Labels are texts used to describe the purpose of the form control. You should associate form controls with a label implicitly or explicitly. This is exposed to assistive technologies and also makes the clickable area larger when users interact with the form field.
Aria-label
This adds additional information about a particular field that can only be accessed by assistive technologies. This overrides any other native labeling mechanism, such as a label element.
<label for='date-of-birth' aria-label="This is for screen readers">Date of birth</label>
<select name='date-of-birth' id='date-of-birth' aria-label="Date of birth">
<option value='1990'>1990</option>
<option value='1991'>1991</option>
<option value='1992'>1992</option>
<option value='1993'>1993</option>
<option value='1994'>1994</option>
</select>
Aria-labelledby
Aria-labelledby allows you to define an ID on an element which you can reference as the label for another element or elements.
<label id="emaillabel">Email Address</label>
<input id="email" type="email" aria-labelledby="emaillabel" />
Aria-describedby
This references an element ID that has further description for the control.
<p id="toppingslabel">Which of these toppings do you prefer?</p>
<div>
<input
type="radio"
id="strawberry"
value="strawberry"
name="toppings"
aria-labelledby="toppingslabel"
aria-describedby="moreinfo"
/>
<label for="strawberry">Strawberry</label>
</div>
<div>
<input
type="radio"
id="vanilla"
value="vanilla"
name="toppings"
aria-labelledby="toppingslabel"
aria-describedby="moreinfo"
/>
<label for="vanilla">Vanilla</label>
</div>
<span id="moreinfo">
Provide additional information relevant to the section referencing it
</span>
Aria-owns
This attribute is used to tell assistive technology that an element that is separate in the DOM should be treated as a child of the current element.
<div role='menu'>
<div role='menuitem' aria-haspopup='true' aria-owns='submenu'>
View More
</div>
</div>
<div role='menu' id='submenu'>
<div role='menuitem'>
Active users
</div>
</div>
Conclusion
Having learnt all these, it is time to get to work. Test your site or web apps and ensure that they are usable. If not, apply the concepts you have learnt to make the web a better place for all. Feel free to learn more about aria attributes.