DEV Community

Cover image for A deep dive into ARIA
Eli H. Schei
Eli H. Schei

Posted on • Updated on • Originally published at

A deep dive into ARIA

Have you heard about ARIA attributes but don’t really understand what they are, or how to use them? Or maybe you know the basics but wan’t to deepen your understanding on the topic? Either way you are in the right place! In this blogpost I will cover what ARIA is, why and when you should use them. I will also go into ARIA roles in debth, and ARIA states and properties.

Prerequesites: I will assume you have some basic understandig of accessibility concepts, if you don’t I recommend to read “Part 1: Introduction” before diving into this blog post.

What is ARIA?

I briefly covered this in “Part 1: Introduction” but thught I should include it here as well.

The MDN Web Docs defines ARIA like this: “Accessible Rich Internet Applications (ARIA)is a set of attributes that define ways to make web content and web applications (especially those developed with JavaScript) more accessible to people with disabilities.”

If a screen reader can’t understand the semantics of your web site content – your site is unaccessible to those who use that kind of assistive technology. This is where ARIA comes in – by adding ARIA attributes to your HTML elements the screen reader can get the context and descriptive details. ARIA attributes have no effect on how the HTML elements are visually presented.

Different types of ARIA

ARIA attributes is a common name for two main categories: “ARIA roles” and “ARIA states and properties”. While ARIA roles describes the type of user interface an HTML element represents, ARIA state and properties describes the current state of the element, and are likely to change as the user interacts with the application. In the next sections we will take a closer look at both roles, and states and properies.

When should you use ARIA?

ARIA are supposed to be a supplement to your HTML. If should focus on making a logical site structure, using semantic HTML elements and giving things descriptive names. Adding ARIA attributes should be a last resort.

That being said, it mostly applies to the use of ARIA roles – since thats quite similar to semantic HTML. ARIA states and properties on the other hand can be used with both semantic or non semantic HTML elements to give the user even more information.

ARIA Roles

There are a lot of different ARIA roles and they are divided into six categories. In general they all describe different types of user interfaces.

Widget roles
Describes interactive components like “button”, “progressbar” or “tablist” (++). Should only be used where there are no semantic HTML elements to match, or if the semantic element is not supported in a commonly used browser.
Use <button> instead of <div role="button">

Composite roles
These roles are typically “parent roles” of widget roles. Like “radiogroup” is the parent of widget-role “radio“.

Document structure roles
Used to describe the structure of a webpage. Like the other roles these should also only be used if there is no semantic element that can be used instead.

Landmark roles
These roles also describes the site structure, but from a higher level. Landmark roles include, but are not limited to, “banner”, “main” and “navigation”.

Live region roles
Used to describe what type of live content can be expected. Includes attributes for “alert”, “timer” and “status”.

Window roles
There are two window roles “dialog” and “alertdialog”. These are used on content that are ment to be displayed as a sub-window, or modal.

You can find a full overview of the different roles on the W3 recommendations site

How to use ARIA roles

Like I mentioned previously you should strive to use the correct semantic elements and only add ARIA to add extra context or information. Lets look at some examples.

//using ARIA role
<div role="banner">
   This is the header area of my website
   <img src="logo.jpg" />

//using semantic HTML
   This is the header area of my website
   <img src="logo.jpg" />
Enter fullscreen mode Exit fullscreen mode

In the above example I use the role “banner” to indicate that this is the main header area of the website. And that this area will contain information such as navigation links, logo etc. But there are also a semantic HTML element that will indicate the same role, .

  • Always exceptions In most cases you want to go with the semantic HTML, but in some special instances you might need to use the role attribute instead. One example of this is if you work on a project with a lot of legacy code and you don’t have the budget to refactor it. Then a quick fix to make it more accessible would be to add the role=”banner”. Or if you have no access to the html you can add the role=”banner” using javascript.

And not every user interface has a corresponding semantic element, and then we can use ARIA roles to make the element accessible. Lets look at an example using a “tablist”.

<div role="tablist">
    <button role="tab"> TAB 1</button>
    <button role="tab" >TAB 2</button>
<div role="tabpanel">My first tab</div>
<div role="tabpanel">My second tab</div>
Enter fullscreen mode Exit fullscreen mode

In the above example you can se that I have given the first <div>a role="tablist". And inside it are two buttons that both have a role="tab". Without these roles it would be impossible for assisitve technology to understand this part of the website.

The elements with the role="tab" controls the visibility of an accosiated elemented with the role="tabpanel". We will take a closer look at how these relationships are configured in the next section about state and properties.

ARIA States and properties

The other category of ARIA attributes are “states and properties”. These will sometimes change as the user interacts with the application. When changes occures the assistive technology is notified and can convey the information to the user.

Difference between state and properties
The difference is subtle and it’s not really important either. But you can think of it like this: a state is likely to change during user interaction, and a property is less likely to change. Lets look at some examples.

  • aria-checked. Is likely to change if the user selects or unselects a checkbox. So this is a state.
  • aria-requiered. The value of this is less likely to change as the user interacts with the site. So this is a property.

ARIA states and properties are divided into four categories:

  • Widget attributes – receive user input and process user actions.
  • Live region attributes – indicates that content changes may occur without the element having focus.
  • Drag and drop attributes
  • Relationship attributes – indicate relationships or associations between elements which cannot be easaly determined from the document structure

Lets continue with our tablist example and add some state and properties to it as well.

<div role="tablist">
    <button role="tab" 
              TAB 1
    <button role="tab" 
            aria-selected="false " 
              TAB 2
<div role="tabpanel" aria-labelledby="tab1" id="tab-1">My first tab</div>
<div role="tabpanel" aria-labelledby="tab2" id="tab-2">My second tab</div>
Enter fullscreen mode Exit fullscreen mode

Above you can see that we have added the attributes “aria-selected” and “aria-controls” to the button elements. aria-selected is in the category ‘widget attributes¨’, and it can have the value true or false. It describes wich of the elements that are currently selected. The other attribute “aria-controls” is a relationship attribute and tells us to wich of the tabpanels the button is connected.

Another example of a relationship attribute is “aria-describedby” where the value points to the ID of the elements that describes the current element.

<button aria-describedby="openDialogInfo">Open dialog</button>
<div id="openDialogInfo">
    This will open the form in a dialog. All changes you have allready made will be lost.
Enter fullscreen mode Exit fullscreen mode

Aria-label vs aria-labeledby
Aria-label defines a string that labels the current element. Only use this if there is no visual label. If there is a visual label use that and add the “aria-labeledby” attribute instead.

Using ARIA state and properties to give feedback on user interaction

Its important to give the user updated info about the result of their interactions. As I mentioned previosuly – if states or properties change the assistive technology is notified and can tell the user what changed. Lets look at some of the attributes that can be used to provide information as the user interacts with your website.

  • aria-invalid. Tells the user if their input is valid. This has four different states: false – which means no errors are detected. grammar – which means grammatical error spelling – which means a spelling error is detected true – which means the input is invalid
  • aria-valuemin, aria-valuemax, aria-valuenow. These attributes are used to tell the user the min, max and current value of an element. The min and max values will stay the same but the valuenow will update based on user input.

To keep this post from getting any longer I will stop here. But there are a lot more attributes and its a good idea to familiarize yourself with them so you know what to reach for to make different interactions accessible.

You can find a full list of the different states and properties here


Did you find this article usefull? Follow me on twitter to be notified when I publish something new!

Top comments (3)

grahamthedev profile image

A great look at a bit more detail.

Just so you know there is a minor mistake with your tablist example, you have an aria-labelledby that is pointing to a non-existent ID.

Also aria-selected="true" on two tab buttons would be an accessibility error that may cause confusion, one should be false or non existent!

One last thing that is particularly unusual about tabs is that it is one of the few times it is recommended that you add tabindex="0" to the tabpanel that is currently active.

Only minor but just thought I would let you know.

Either way have a ❤ and a 🦄!

elischei profile image
Eli H. Schei

Thanks for the feedback! :) The two first are copy paste errors on my part! And I didn’t catch it when reading through, so Thank you for pointing those out! I will update the post and fix the errors.

The tabindex usecase I wasn’t aware of, so I learned something new! Thanks! :)

grahamthedev profile image

No problem, it was a great deeper dive and I know what it is like with examples!

I look forward to the next entry in the series! ❤