Accessibility Tip: Beginners guide to ARIA

Last updated on January 03, 2022ArticlesTechnical-guides

Intro to ARIA

ARIA is a specification that defines how we should design interactive features on websites, and describes how to make them accessible.

It explains how to tell screen readers what type of feature (e.g. a tab list with multiple tabs) something is, so when screen readers interact with it they can accurately describe it to users.

There are two main parts: role and ARIA properties.

The roles are when you want to describe an element and explain what it is. For example if you have a custom checkbox item (should probably avoid doing that!) then you might have <div role="checkbox">click to toggle something</div>. Screen readers will then know its not just a div, but a checkbox. (Other important accessibility things such as focusable state are removed from this example).

Then aria properties are properties that you can set on elements, for example <div aria-hidden="true">Screen readers will ignore this</div> (aria properties are only used by screen readers / assistive tech, so setting aria-hidden will hide it only for those). Or <button aria-label="Show more button">+</button> which will let screen readers describe it as “show more button” instead of “plus sign”.

Table of contents

Who adds ARIA to your site?

This is something for your developers. Generally if you’re adding functionality via JavaScript (this includes anything in React/Vue/Angular) then you will need to consider ARIA to make it accessible.

What browsers use ARIA?

Assistive technologies use ARIA. So if you have a screen reader (even if its by setting screen reader on in your operating system and then you use Chrome), ARIA will be used.

What can you do with ARIA?

You can use ARIA to tell browsers (screen readers or other assistive browsers) semantic information about elements.

For example you can tell them what an element is labelled as (aria-label="open new window or aria-labelledby="someElementID"), or say if an element is expanded (useful for dropdowns) with aria-expanded="true").

When to use ARIA

Always avoid using aria if possible. There are lots of built in elements in HTML5 - they are designed to already be fully accessible so do not try to reinvent the wheel.

ARIA roles (in detail)

HTML has a lot of built in elements - such as <input type="checkbox" /> or <img src="..."/>.

But it doesn’t have everything - for example tabs. We can recreate tab functionality (often with <div> elements). But unless you use ARIA then screen readers will not know they’re anything special other than a standard <div> element.

So we can use ARIA roles to tell screen readers what type of feature something is. Then the screen reader will tell the user what it is (e.g. a tab list).

Landmark roles

If you can visually see then you can probably clearly make up where the headers of a site site, what the nav is, where the footer is, what a form is.

(note: we should always aim to use built in things like <form> so screen readers will know its a form. But sometimes <div role="form"> is needed.)

But screen readers will not be able to distinguish that. So we should use ARIA landmark roles so screen readers can describe areas of the site correctly.

read more here about landmark roles

Try and use built in HTML5 elements for landmark roles. If you use <header> it automatically assigns the correct role.

Examples to use: <header> (automatically assigns role="banner"), <main> (role="main"), <nav> (role="navigation"), <form> (role="form")

Roles to replicate existing HTML elements

Maybe for some reason you want to reimplement a checkbox, and instead of <input type="checkbox"> you’ve ended up with a div.

You can use roles such as role="checkbox" to tell screen readers that this is really a checkbox.

Other examples:

  • role="button"
  • role="img"
  • role="textbox"

(always try to avoid using these - the standard HTML5 element for these roles already exist and have correct accessibility already baked in).

Widget Roles

If you create something that has some form of interaction then you should consider the widget roles. They are for when you implement something such as a tab/tablist, a tooltip etc.

The following example shows a composite widget (tab/tablist/tabpanel). Note - this is a very basic example, no aria properties (such as showing what is currently shown tab) are added.

<ul role="tablist">
    <li role="tab">tab 1</li>
    <li role="tab">tab 2</li>
</ul>
<div>
    <div role="tabpanel">content for tab 1</div>
    <div role="tabpanel">content for tab 2</div>
</div>

Note on the Application role (role="application")

The role="application" role is a document structure role.

In most cases you should avoid setting this unless you really know what you’re doing.

When the application role is applied, it is up to the developer of the page (or application!) to handle all interactions such as keyboard event handlers.

If you set role="application" then screen readers will have no access to default accessibility information (such as labels).

Find more about it on MDN https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/application_role

<div role="application">
  ...
</div>

ARIA properties (in detail)

There are lots of ARIA properties. Here is a list…

  • aria-activedescendant
  • aria-atomic
  • aria-autocomplete
  • aria-busy
  • aria-checked
  • aria-colcount
  • aria-colindex
  • aria-colspan
  • aria-controls
  • aria-describedby
  • aria-description
  • aria-details
  • aria-disabled
  • aria-dropeffect
  • aria-errormessage
  • aria-errormessage
  • aria-expanded
  • aria-flowto
  • aria-grabbed
  • aria-haspopup
  • aria-hidden
  • aria-invalid
  • aria-label
  • aria-labelledby
  • aria-level
  • aria-live
  • aria-modal
  • aria-multiline
  • aria-multiselectable
  • aria-orientation
  • aria-owns
  • aria-placeholder
  • aria-posinset
  • aria-pressed
  • aria-readonly
  • aria-relevant
  • aria-required
  • aria-rowcount
  • aria-rowindex
  • aria-rowspan
  • aria-selected
  • aria-setsize
  • aria-sort
  • aria-valuemax
  • aria-valuemin
  • aria-valuenow
  • aria-valuetext

You will often change the aria properties as users interact with your features. For example you might set aria-invalid as true when an input value is not valid.

Another example might be setting aria-checked on a checkbox when someone clicks it (remember: you should aim to use <input type="checkbox"> and not reimplement things from scratch)

ARIA live regions (announcing changes)

By default a screen reader will read out all content on a page, and then leave it alone. If you change content, it won’t read the updated content.

You can change this with aria-live (and role="alert" which automatically sets up aria-live).

There are three options:

  • aria-live="off" - this is the default for most elements, and any changes in text content will not be announced
  • aria-live="polite" - changes to the text content will be announced at the next time the screen reader is idle - in other words, when it has finished reading out whatever it is currently reading.
  • aria-live="assertive" - will read out changes to text content and interrupt the screen reader even if its currently reading something out.

Example of ARIA live

<div id="announce" aria-live="polite"></div>
// get a button
const aBtn = document.querySelector('#some-button');
const announceDiv = document.querySelector('#announce');

// when clicking the button, set text content
// in the announce div
aBtn.addEventListener('click', () => {
    announceDiv.textContent = 'Read something out to the user';
})

Tips about ARIA live announcements

  • keep the messages short and to the point
  • Does the whole region need to be re-read out when it changes? By default it won’t (aria-atomic="false" is the default). But you can set it with aria-atomic="true")
  • when adding an aria live element, aim to set the initial text empty (and then populate it with the announcement) instead of adding the element with the text content already set.
  • using role="alert" will automatically set aria-live="assertive"

Found this post useful?

Please consider sharing this link with your work colleagues or on social media. There are no ads on my site, I just want to promote accessibility.

Found an issue? please point them out - let me know if there is a mistake and I'll update it

Follow me on Twitter: @A11yForDevs. I post links to interesting a11y articles and resources.

More posts

Welcome to Accessibility for Developers

New to accessibility?

Accessibility for Developers

This is a free site to give advice on how to make your website accessible

I have been a software developer for nearly a couple of decades, and really want to help promote better accessibility in apps and websites that we, as developers, create! Accessibility isn't very difficult, it is just important to be aware about it and understand it.

If you spot any mistakes or have any suggestions, ideas or collaborations please check out my contact page.

Important: The information on this website is for general informational purposes only. I make no representation or warranty, express or implied. Your use of the site is solely at your own risk. I've tried my best to make sure all information is accurate, but I am just a software engineer (not an accessibility expert).