An Introduction To WAI-ARIA’s Roles, States, And Properties

Assistive devices, like screen readers, need to understand web content and applications before they can communicate the information to persons with disabilities. Much of the time the HTML we write provides those semantics. Sometimes it doesn’t, and that’s where WAI-ARIA comes in.


For the last few weeks I’ve been talking about accessibility. I shared my thoughts as I approached the series, tried to define what accessibility is and means. and then walked through the Web Content Accessibility Guidelines (WCAG 2.0). Here’s the series up to this point.

As you can probably guess from the first paragraph, today I want to talk about ARIA, more specifically the Web Accessibility Initiative for Accessible Rich Internet Applications, otherwise known as WAI-ARIA.

Consider today an introduction. I want talk about some basic ideas and concepts and then walk you though an example using ARIA. I think the example helps explain the reasons for using ARIA.

Over the next few weeks, I’ll dig a little deeper into ARIA specifics and point you to resources for the complete details.

Introduction to WAI-ARIA

For web content to be accessible, it must convey semantic information about its structure and behavior to assistive devices. WAI-ARIA exists to convey the semantics when native HTML isn’t enough.

ARIA is primarily for developers who create custom widgets and other components that don’t carry the necessary information. Odds are Javascript is involved with the widget creation and can’t doesn’t carry the appropriate semantics by default.

Working with ARIA isn’t any different than adding markup to a line of text to convey to a browser that the text is a level 2 heading or a list item inside an ordered list or a checkbox. The WAI-ARIA spec defines a number or roles, states, and properties that you can use to markup your document and deliver the appropriate semantic information.

Like many of the documents guiding us in creating accessible sites, and like HTML itself, the ARIA spec is ultimately a list of markup that you’ll slowly memorize as you begin to use it.

There are far too many roles, states, and properties to try to do justice to them in a post or series. My goal is once again to offer an overview of ARIA and then point you in the right direction for more learning and reference.

Speaking of more, Šime, pointed me to an article that offers a very good introduction to WAI-ARIA. I’ll cover much of what the article discusses over the next few weeks and I recommend giving the article a read.

Roles, States, and Properties

ARIA allows you to add semantics that override those that HTML elements and their attributes provide natively. It allows you to add semantic meaning when developing something in a non-standard way. For example using a div or span to create a button.

ARIA offers three ways to communicate semantics.

  • roles define the component’s purpose in the interface
  • properties define characteristics of the component
  • states define the current conditions of the component

Together states and properties are called ARIA attributes and they all start with aria- as in the aria-checked state, which can be set to true or false. Either states or properties can be used to show that something about the component has changed.

Again, when the native semantics of the HTML being used aren’t enough you should add the appropriate roles, states, and properties that communicate the necessary semantic information to assistive devices.

An Example of WAI-ARIA in HTML

Before diving into roles, states, and properties over the next few weeks, I want to present a simple example that makes use of all three. I think the example will be easy enough to follow and I think it will provide some useful context for the deeper look.

Here are a couple lines of code you might use to develop a checkbox as a required form field. No ARIA is used, but the code still communicates important information to assistive devices.

<input type="checkbox" id="check" required="true" />
<label for="check">Check Me (required)</label>

An input with type=“checkbox” communicates its role in the interface as a checkbox and with it come some properties and attributes that can be set with HTML such as required (property) or checked (state). Since the checked attribute isn’t set, the default state of the checkbox is unchecked.

I added the HTML5 required attribute and the word required in the label to indicate the checkbox must be checked. Maybe it’s a checkbox to show you’ve read the terms and conditions of something.

Not all browsers support the required attribute, but for those that do, which includes some screen readers, this code conveys the necessary semantic information. It has a role, a property, and a state, and the label uses a for attribute to indicate it goes with the input.

Let’s pretend we can’t use an input for the checkbox for one reason or another. Let’s say we have to use a span. The span can be made to look like a checkbox through CSS and Javascript can provide the functionality. For the sake of simplicity I won’t show either, but I assume you know both can be done and you accept that a span can be made to look and function like a checkbox.

We might start with code like this:

<span id="check"></span>
<label for="check">Check Me (required)</label>

Unfortunately spans are generic containers that don’t come with a role or attributes like required and checked. While we could use CSS and Javascript to make the span look and act like a checkbox, that information isn’t being delivered to assertive devices.

We’ll use ARIA to convey the semantics. Let’s start by adding a role of checkbox.

<span id="check" role="checkbox"></span>
<label for="check">Check Me (required)</label>

Now assistive devices will understand this span should be treated as a checkbox.

We still need to communicate that this checkbox is required and unchecked by default. We can communicate the first by adding the aria-required property and the second by adding the aria-checked state.

<span id="check" role="checkbox" aria-required="true" aria-checked="false"></span>
<label for="check">Check Me (required)</label>

Again, while I haven’t shown either we’d need to style this “checkbox” with CSS and give it checkbox functionality with Javascript, but with ARIA we’ve been able to communicate to assistive devices that this span should be treated as a required checkbox that is currently unchecked.

It’s also important to keep in mind that the reason we added ARIA to this example is because we started with an element that didn’t communicate the appropriate semantics. Had we stuck with an input of type checkbox with required and checked attributes, the ARIA wouldn’t be necessary.

Additional Resources

As I worked my way through this series I linked to articles I think you might find helpful. Some never found there way in so I thought I would present a few additional resources.

Closing Thoughts

ARIA exists to help web designers and developers communicate semantic information to assistive devices, when the native semantics of the HTML aren’t enough. Ideally you want to stick with the native semantics, but sometimes you can’t for one reason or another.

When you need to you add the semantic information through different ARIA roles, states, and properties, depending on the specifics of your interface component.

Another reason why you might add ARIA is when no HTML element carries the proper semantics. Some roles, states, and properties are currently not available natively in HTML5 and you have to use the ARIA to communicate the semantics.

Hopefully this served as a good introduction if WAI-ARIA is new to you or a simple review if you’re more familiar. There’s certainly more to ARIA than what I’ve shown here.

Over the next two weeks I want to dig a little deeper into roles, states, and properties and look at the roles model including ARIA’s supported states and properties. I’ll finish this part of the series the following week with some general guidelines for working with ARIA.

Download a free sample from my book, Design Fundamentals.


    • Thanks. I added the link to the resources in the posts. I’ll dig through more when I have some time. The next time I talk accessibility I wanted to offer more examples so it’ll fit in fit in well the next round too.

      Thanks again.

  1. Hi Steven, a few comments:
    label elements can only be associated with labelable elements in other words the labele elment won’t work as intended when you asscoiate it with a span, regardless of the role you apply to the span. Another minor point: the rquired attribute is a boolean attrbute it presence is = true its absence is = false, required=true is not conforming using produces the following “Error: Bad value true for attribute required on element input.”

    • Thanks Steve, My bad. This all pretty new to me and I’m still finding my way around. I was hoping I picked a simple example in order to explain the concepts, but I guess I didn’t choose the best example I could.

Leave a Reply

Your email address will not be published. Required fields are marked *