Accessibility Series: An Unreasonably Long Introduction To ARIA (With Example Implementation)

Alexander Nied
24 min readJul 14, 2021

Let’s Get Started With An Unreasonably Long Preamble

When I first started this blog series (back in 2019, with an 18 month break after the second post 😔) one of my goals was to become an “expert” in ARIA and then write a post on the topic. In an effort to get myself started, I kept looking around on the internet for a quick introduction to ARIA for the web. What I wanted was a five-minute, crib notes version that I could just scan to get the basics; I figured once I had that, I could start peppering in ARIA here and there in my work and fill in the gaps in my knowledge as needed. I never found a cheat sheet like this, and naïvely assumed it was because nobody had written one yet. It was only after I really started to read more about ARIA that I learned that, just as web accessibility is a complicated series of cross-cutting considerations, perhaps ARIA simply does too many things to be covered in a cheat sheet. Perhaps a five minute intro to ARIA would be like creating a five minute intro to speaking French or playing piano.

A basket full of baguettes
Just hold one of these when you talk and you should be fine…

The idea of being an “expert” means different things in different contexts. For the purposes of professional web development, I consider myself (fairly, I hope) a JavaScript expert. However, if you wanted someone to write a book about JavaScript, its history, and the complete language (including the “bad parts”), I’m probably not your guy. I’m a practitioner of JavaScript; I’m not a professor of JavaScript. I can’t give you the 15-minute version of JavaScript’s origin story, nor can I tell you how to use the with or label statements because in 2021 probably nobody should be using them.

Two O’Reilly Programming Books- the first is “JavaScript: The Definitive Guide” and is roughly three inches thick; the second is “JavaScript: The Good Parts” and it is only about one inch thick.
A little light reading

Today, as I write this, I don’t feel like an expert practitioner of ARIA nor am I a professor of ARIA. However, I have been trying to (responsibly) increase my usage of ARIA over the last year and a half, and I’m feeling like a solid ARIA beginner.

One thing I keep reminding myself — being an expert practitioner does not mean memorizing the API of a language or module. I consider myself a JavaScript expert, but I still have to look up the signature for an Array.prototype.reduce() callback every. single. time. I consider myself an HTML expert, but I certainly haven’t memorized every single HTML element that exists. Did you know that there’s a <ruby /> tag? I sure didn’t! I’m ten years into professional web development and I just learned about it a week ago!

Rather than rote memorization, I’d assert that expertise is about knowing broadly what nature of things is in a language or API, and understanding how best to utilize them in a manner that is effective, maintainable, and scalable. Furthermore, I’d add that knowing where to look to find the best reference material and how to debug what you have created are other tentpoles of expert status.

All this is to say: I’m not an expert, but I’m learning. And part of the learning process has been to identify what ARIA can do, what it can’t do, what it shouldn’t do, and the other rules and guardrails that need to be adhered to when using it. Since my goal here has been to learn by blogging, I decided to share a top-level, introductory pass to what ARIA is all about, and what resources should be referenced when leveraging ARIA in your projects. It is a bit lengthy, but should hopefully be shorter than reading the spec itself, and provide sufficient information to get you started actually using ARIA in your work. Furthermore, we’ll create two example implementations as an exercise to provide a practical understanding of how ARIA is used.

What Is ARIA

A Lego minifigure of an opera singer
I’m *so* happy this picture exists…

ARIA stands for Accessible Rich Internet Applications. While some web developers may only vaguely know it as “some accessibility thingy” ARIA is a W3C spec that has been in recommended status since 2014. The high-level description is that ARIA is a collection of attributes that can be added to HTML elements in order to change how they are understood and communicated by assistive technology.

We are going to spend a lot of time in this article discussing context and rules for how to use ARIA before we get to examples where we build interactive accessible components using ARIA. If you’re super eager you can skip straight to the examples, but I strongly urge you to make sure you circle back to read the following sections; it might save you from writing bad ARIA, which the W3C tells us is worse than no ARIA at all.

What Can ARIA Do?

Most users who don’t leverage any assistive technology when web browsing are probably unaware that, in addition to the visual display they see on the screen, the browser also renders an “accessibility tree.” This is a sort of overlay on the DOM tree, and contains semantic metadata about the elements on the page. This can include:

  • Names and Descriptions
  • Roles (such as “checkbox” or “heading”)
  • States (like “checked/unchecked,” “expanded/collapsed,” etc)
  • Linkages (such as descriptions of when an element controls another element, or contains another element, etc).

This accessibility tree is what is leveraged by screen readers in order to navigate and describe the content on the page. A page with a complete, rich accessibility tree will be more easily accessible to users leveraging a screen reader. A page with an incomplete accessibility tree (or even worse, an incorrect accessibility tree) could be difficult or impossible for a screen reader and/or keyboard user to interact with.

While ideally one leverages proper native elements in a manner that the page’s accessibility tree is rendered automatically in a complete and robust manner, this is sometimes not possible or not pragmatic. In these cases, ARIA can be leveraged in order to manually alter the accessibility tree in a manner that makes the page properly accessible to those using assistive technologies that rely on the accessibility tree. Additionally, ARIA can manage alerting users who cannot see the screen to dynamic content updates that they would otherwise miss (for example, a pop-up notification for a new message).

“ARIA can both cloak and enhance, creating both power and danger.” — WAI-ARIA Authoring Practices 1.1

One crucial word of caution: while ARIA can aid in adding or enhancing accessibility, it can also destroy accessibility. Improper tagging can break native accessibility, or render a page in a confusing or fully unusable manner for assistive technology. This appears to be a major concern for the creators of the ARIA spec; they have a section in the ARIA Authoring Practices document entitled “No ARIA Is Better Than Bad ARIA,” in which they note that “ARIA can both cloak and enhance, creating both power and danger”. Some of these “danger” scenarios are covered in the “Rules of ARIA,” specifically “Rule #2: Never change native semantics” and “Rule #4: Don’t hide focusable elements from the accessibility tree;” however, these don’t encompass all cases of problematic implementations that could negatively impact accessibility. For this reason, it is important to know who is using ARIA and how (more on that later in the article), as well as how to thoroughly test any ARIA implementation in which there is a question as to how it might work.

With great power comes great accessibility…

What *Can’t* ARIA Do?

As I have previously discussed in this series, web accessibility is more than just keyboard and screen reader support. While ARIA can make a difference for users leveraging assistive technologies that interact with the browser’s accessibility tree, it will do nothing for accessibility issues for users not using assistive technology. For instance, text-to-background contrast issues, inaccessible colors for users with color blindness, or motion issues for those with vestibular disorders will be completely unaffected by anything you do with ARIA.

Beyond this, it is important to note that ARIA only affects the accessibility tree; it will make no other changes to the page. ARIA cannot change the way the page is displayed, nor the DOM, nor any interactivity on the page. ARIA changes are generally invisible to users not leveraging assistive technologies like a screen reader. This is particularly important as several of the W3C official role descriptions require keyboard interactivity — in fact, the “third rule of ARIA” is “all interactive ARIA controls must be usable with the keyboard.” This keyboard functionality will not be magically imbued into the page by adding an ARIA role; it will have to be manually added via JavaScript.

When Should ARIA Be Used?

The “first rule of ARIA” in the spec is “Don’t use ARIA.” This is because much of the functionality ARIA provides can be accomplished without ARIA by simply using proper semantic HTML and best practices. For instance, why use a <div/> with role="nav" when using a <nav/> element would implicitly provide that role to the accessibility tree?

However, this is not always the case. Sometimes you have to create a custom checkbox treatment (or other custom form element) that is impossible to achieve with the native element. Or perhaps you are creating a widget or control that doesn’t have an analogous HTML native element. Or maybe you are leveraging a library that uses inaccessible elements out of the box. For these cases, ARIA can help provide the roles, descriptions, states, and relationships in the accessibility tree that would otherwise be missing.

How Is ARIA Consumed?

One of the biggest challenges of ARIA is that it is consumed by a wide variety of screen readers that have different levels of support for the features ARIA provides. I’ll admit that my experience is mostly limited to VoiceOver on macOS, although the feature set is, I believe, relatively typical of most screen readers. With VoiceOver, you can navigate through the content on the screen using the keyboard. When VoiceOver focuses an element, it will read additional information about the element’s context in the accessibility tree — its role, its state, text that may label or describe it, and how to interact with it using VoiceOver and the keyboard. Furthermore, VoiceOver provides a way to quickly list and interact with page components by type — for instance, VoiceOver can list all anchors on the page, or all headings, or all landmark roles.

Understanding how your page is navigated with a screen reader can be aided by the accessibility dev tools in the browser, but I’d caution against considering it a complete replacement for actually testing with a screen reader. I’ll admit this is an area where I’m learning to practice what I preach. Occasionally I’ll think that I have a page nice and accessible, only to actually try navigating it with VoiceOver and discover issues. While it would also be advisable to test with many different screen readers, this is not always practical or possible — it is worth noting, though, that there are example videos on YouTube of individuals demoing popular screen readers, to give you a sense of how they work.

Who Uses ARIA?

This is an interesting question. As near as I can tell, the general consumer of ARIA tagging is screen readers; other assistive technologies besides screen readers exist, but I don’t believe they are usually leveraging ARIA. However, ARIA tends to go hand-in-hand with keyboard usage; while ARIA won’t change the interactivity for a page, we know that the ARIA spec requires that interactive ARIA elements be usable with the keyboard, and that the instructions for implementing a proper interactive widget with ARIA will include rules for keyboard navigability. So, with this context, we can break down ARIA usage by consideration of who can/cannot see the screen, and who can/cannot use the keyboard, and get some perhaps surprising results:

Table entitled “Who Relies On ARIA Based On Ability To See The Screen And Keyboard/Mouse Usage.” The table has the column headers “Users Who Mostly Navigate With The Keyboard” and “Users Who Mostly Navigate With The Mouse.” The table has the row headers “Users Who Cannot See the Screen” and “Users Who Can See the Screen.” The contents of the cells is discussed in detail below; the table is merely a visual aid, not the sole conveyance of the information it contains.
  1. Users who interact with the page mostly with the keyboard (or other assistive technology) and cannot see the screen: This is probably the most commonly considered use case. It would encompass users with a visual impairment that makes it difficult or impossible for them to see the content on the screen, who thus use a screen reader and navigate with the keyboard. Their browsing experience is impacted heavily by the accessibility tree of the document, and thus they will be directly consuming widgets implemented with ARIA.
  2. Users who interact with the page mostly with the keyboard (or other assistive technology) and *can* see the screen: This could be users without any visual impairment who simply prefer using a keyboard, or perhaps who have other disabilities or injuries that prevent them from using a mouse. Although they are not leveraging the screen reader, they rely on the accessibility tree being properly structured and interactivity properly wired for keyboard use, which would be the case for widgets properly implemented with ARIA.
  3. Users who interact with the page mostly using the mouse and cannot see the screen: I am relatively confident that this user doesn’t exist, or is quite rare; I imagine being unable to see the screen and cursor position would make this a relatively unproductive way to use the web. However, I am happy to be proven wrong if anybody wishes to do so in the comments section.
  4. Users who interact with the page mostly using the mouse and *can* see the screen: This is probably most web users on a laptop or desktop computer. And most of them probably do not leverage ARIA. However, there is the exception of users who have difficulty reading. This could be users who cannot read due to an impairment like dyslexia, or who are not native speakers of the given language and can speak it but cannot read/write in it, or users have difficulty reading due to injury, or who didn’t learn to read for other reasons. Regardless of why, these users may be using the mouse to highlight text and have the screen reader speak it aloud to them. Most of the time they can manage this just fine without ARIA. However, ARIA can negatively impact their experience if not implemented in a way that considers these users. For instance, text that is hidden from the screen reader using aria-hidden and then rendered invisibly for screen readers will not be accessible to these users. Similarly, text in an image that is then made accessible to screen readers using off-page text will similarly be inaccessible to these users. As such, it is imperative that these users be considered when using ARIA to improve accessibility.

How To Use ARIA

The Rules Of ARIA

Before we dive into our example, we should review the “Rules Of ARIA.” The W3C places these rules immediately after their brief introduction on the Using Aria page, so it seems wise to at least briefly enumerate them here:

A meme of a scene from the film “Fight Club,” in which Tyler Durden (Brad Pitt) addresses a gathered crowd in what appears to be a dimly lit basement. The meme text: “The first rule of ARIA… is don’t use ARIA.”
I’m definitely the first person to come up with this hilarious and original joke.

xRule #1: Don’t Use ARIA
This is perhaps the most important rule. The basic premise is this: If you can achieve the desired accessible result using the native, built-in HTML API, prefer this over using ARIA to wire in accessibility after you’ve written inaccessible markup.

Rule #2: Don’t Change Native Semantics
This rule basically exists to tell you not to start changing native built-in accessibility with ARIA — this way lies madness. For instance, don’t try to take an anchor (which has a native role of link) and try to make it into a heading by giving it role="heading". Instead, choose generic wrappers without built-in accessibility, like a <div> or <span>, to augment with ARIA (or, even better, just wrap the anchor in a <h1>-<h6> and don’t use ARIA at all — see Rule #1).

(For what it is worth, the rule also specifies some circumstances under which it might be acceptable to do this.)

Rule #3: If It’s Good Enough for the Mouse, It’s Good Enough for the Keyboard
Another critical rule: if you have an interactive element, it must be interactive by keyboard. This is intended to prevent developers from creating components that are interactive when clicked or hovered with the mouse but are inaccessible for a keyboard user. Frequently the W3C accessible widget design patterns document will include requirements/instructions for proper keyboard accessibility, so look there to get started.

Rule #4: Don’t Hide Focusable Elements from the Accessibility Tree
If an element is focusable by the keyboard, then it should not be hidden from the accessibility tree. This seems super obvious when you think about it; it’s like having a rule that says “the elevator door should always open when it stops on a floor to drop someone off” or “a light switch should do something when you flip it.” But apparently it was a frequent and/or compelling enough issue that the W3C made it a rule of ARIA.

Rule #5: Interactive Elements Must Have an Accessible Name
Marked as a “work in progress” as of this article’s release, this rule states that an accessible name is required for any interactive element. For native HTML, this is generally achieved using a <label> element wired to a control via wrapping or by leveraging the for attribute. However, a <label> element will not automatically provide a name to a non-labelable element, even if it is given a role that corresponds to a labelable element. Instead, the aria-label or aria-labelledby attributes should be used.

ARIA Example Implementation

ARIA has several accessible roles that can be applied to elements in an HTML document. While roles are not necessarily the most fundamental component of ARIA accessibility tagging, they provide us with a nice jumping-off point for creating widgets that leverage several concepts in the ARIA API as well as with several considerations of how to use ARIA judiciously. Furthermore, the W3C provides an ARIA Authoring Practices document that includes descriptions and requirements for complete role implementations as well as working example implementations. For this reason, we’ll be using two separate roles to build example components.

Checkbox Example

A checkbox is a good starter example because it nicely illustrates the cost in effort for creating custom versions of native controls. For contrast, let’s take a look at a native implementation of a checkbox:

That’s it. Easy, right? Here it is working in a

It requires very little code, and it’s accessible and keyboard navigable right out of the box.

SO — how would we build our own custom implementation that we could make properly accessible using ARIA?

The first thing I always do when I need to implement some custom control in which I’ll need to manually wire in the accessible bits is to check the WAI Best Practices: Design Patterns And Widgets document to see if the control I am building has a predefined design pattern I can work from. As expected, this document contains guidelines for creating an accessible custom checkbox. Even better, most of these design patterns also include an example page that can be used to further understand the implementation and to check your own implementation against to compare and make sure you have captured all the necessary requirements; this is the accessible custom checkbox example page.

Let’s first look at what our naïve, inaccessible version of a custom checkbox might look like:

This is already a lot more code! What we have here is a series of generic <span> containers that accomplish the work of the label, checkbox, and checkmark. We listen on the click of the fake checkbox itself, and toggle a .hide class on the fake checkmark. You can see this in action below:

This works, but it has several problems. Before we even get to the accessibility issue, we are using the DOM to maintain state based on the presence or absence of an arbitrary .hide class. This is flimsy; we would be better off maintaining some separate data-model in JS, or at least using a data attribute if we intend on using the DOM as the source of truth for state.

The next problem is that there is zero accessibility beyond those users who see the screen and use a mouse or touchpad. There is no way to focus our custom checkbox or check and uncheck it with the keyboard. There is no accessible name, which we can see by opening the dev tools and inspecting it. Clicking the fake label doesn’t actually toggle the checkbox, something that works out of the box with our native implementation. There is no role to indicate to a screen reader that this is a checkbox, nor any accessible indication of the checked/unchecked state.

Luckily for us, ARIA provides us the API to accomplish our goals as well as some excellent documentation as to how to go about doing so.

If we visit the WAI ARIA Authoring Practices Design Patterns doc for checkboxes we can track down all the requirements needed to wire this up properly in ARIA:

  • The ability to focus with the keyboard and change the state with the spacebar
  • A role="checkbox"
  • An accessible label
  • Checked state managed with aria-checked
  • Additionally grouping and labelling under certain conditions

Let’s take a look at an implementation now that meets all these requirements:

So what have we changed from our initial implementation in order to meet the requirements defined by WAI?

  • We have added an additional handler on the keydown event that is sniffing for the spacebar to determine whether or not to run the handler function
  • We have expanded the click handler to the label
  • We have made our custom checkbox focusable by setting tabindex="0", and ensured that the focus indicator would be visible
  • We have given the custom checkbox a role="checkbox"
  • We have wired up an accessible name by pointing the aria-labelledby attribute at our fake label <span>
  • Rather than toggling an arbitrary class, we now toggle the aria-checked attribute, and use CSS to hide/show the checkmark on the basis of this attribute
  • We have hidden the actual checkmark from the accessibility tree, as the checked state is properly tracked in ARIA and reading it would only be confusing

You can see this implementation, next to the native implementation, in the sandbox below:

As you can see, this is a lot more code than the native checkbox to achieve the same effect. In most cases, it would probably be preferable to use a solely CSS-based approach to customize a checkbox than attempt to recreate one entirely using JS and ARIA.

Tabbed Container Example

A tabbed container is a better use-case for ARIA, as it represents UI/UX that isn’t natively available in HTML.

A tabbed container is a widget with several “tabs” along the top that correlate to some topic to be shown in the “main” area below (or to the side). When a “tab” is activated, the associated content area shows the content correlating with that tab — usually some kind of visual treatment is given to the currently active tab to differentiate it from the other tabs.

As before, let’s start with an inaccessible example of what this widget would look like:

Here is a working example:

Just as before, this works just fine for a user who is looking at the screen and mostly navigating by mouse. However, a user using the keyboard and/or a screen reader would have a very different experience. First and foremost, the interactive controls — the tabs — are not focusable, and thus cannot be accessed or controlled via the keyboard.

However, this is not the only issue here. There is also the fact that the inactive pane content is still rendered and accessible in the DOM; the active content is given a higher z-index, but the inactive content is still beneath it. As such, a screen reader would traverse all the tab names, then all the content in order. Or, if a keyboard user was tabbing through focusable elements, the active element could be a link or button in a pane that isn’t visible on the page. This, obviously, represents a bad user experience.

So how do we fix it? As before, our first stop is the “tabs” section in the WAI ARIA Design Patterns docs and the linked example implementation of an accessible tabbed container. There we find the various ARIA tagging needed:

  • A container of role="tablist" that contains all the tabs (with role="tab") with an accessible label
  • The content for each tab is in a container marked as role="tabpanel", and the relation to the tab is wired via aria-controls and aria-labelledby
  • Some additional tagging where applicable

Furthermore, there are lengthy and specific keyboard controls designated for navigating tab content:

  • tab keypress focuses into the active tab in the tablist, an additional tab keypress will focus into the next focusable element
  • When focused on a tab in a tablist, arrow keys (and optionally the home and end keys) can navigate the tabs; if the content loads quickly without performance implications or delay (for an AJAX request, for instance) then the newly focused tab can and should be automatically activated
  • Additional keyboard navigation rules for specific applications

With these in mind, we can start reworking our inaccessible tabbed container example to be accessible.

The first thing we will focus on is wiring up the proper ARIA tagging — assigning roles and wiring relationships:

So what have we done? We have:

  • Wrapped the tabs in a role="tablist"
  • Given role="tab" to each tab
  • Given each content pane role="tabpanel"
  • Associated each tab with its pane using aria-controls
  • Added aria-selected to indicate the active pane in the tabbed container
  • Reused quite a bit of CSS by simply selecting by ARIA attributes
  • Updated our styling to give all non-active tab panels display: none, so that they cannot be accidentally accessed via screen reader or keyboard focus when not visible

We can now look at the accessibility tree in our dev tools and see that all the wiring in our implementation matches the example.

A few key places I deviated from the WAI example:

  • The WAI example uses button elements with role="tab" for the tabs, whereas I used div elements. I imagine the reasoning they opted for this route was it gave them some keyboard focus for free; however, it would seem to me to violate the second rule of ARIA, which states that you should never reassign a role using ARIA, so I opted to use a role-less element instead. It is possible, however, that they made this decision because the button represented a “fallback role,” which the second rule deems as an acceptable instance of role reassignment. You might have to use your own judgement in some of these cases.
  • The WAI example leverages hidden to hide elements; however, as display: none should be sufficient for both the visible UI as well as preventing content from being in the accessibility tree, I opted for this approach.

Now that our accessible states and relationships are wired up, we have to add keyboard access to meet the requirements in the design pattern doc and adhere to the third rule of ARIA. Because all of our panel content loads quickly without performance implications, we will adhere to the recommendation of loading the content automatically as the user navigates through tabs. We’ll do some careful additions of tabindex attributes and add the following code to drive keyboard controls:

We’ve abstracted the code that actually focuses a tab into its own function that we call from the click handler. Then, we’ve added a keydown handler that sniffs on whether the pressed key was an arrow key, then interrogates the current focused tab and figures out what the next focused tab should be, including checks to allow the focus to wrap when navigating past the end of the tabs. Beyond that we’ve added some additional handling around tabindex. I also did some adjustments to the focus outline for visibility in this example; please note that this is often considered an accessibility antipattern.

You can see the working example below:

While this is a lot of code, it provides us with an interactive page element that includes full accessibility like a native element might provide. We did it!

Well, actually…

Photo by Zachary Kadolph on Unsplash

I misled you with these contrived examples. While there are some special cases and contexts in which ARIA should be included inline, in all other cases they should be added after the initial render using JavaScript. Why? From the W3C Using ARIA doc:

If the ARIA role or aria-* attribute does not rely on scripting to provide interaction behavior, then it is safe to include the ARIA markup inline. For example, it is fine to add ARIA landmark roles or ARIA labeling and describing attributes inline.

If the content and interaction is only supported in a scripting-enabled browsing context, i.e. Google docs (its applications require JavaScript enabled to work), it is also safe to include the ARIA markup inline as the application simply will not work (for anyone) without JavaScript enabled.

Otherwise insert, change and remove ARIA via scripting.

Not everyone will always have JavaScript enabled. The reason why needn’t really concern us — we should, when possible/practical/pragmatic, strive to provide a usable experience for all users, including those with JavaScript disabled. So, with that in mind, we should rework our tabbed interface to make it fully usable and accessible with JavaScript disabled, and then use JavaScript to assemble and wire the ARIA-powered experience. Thinking from a progressive enhancement perspective, we might adopt an initial design with all content showing by default in the view when it is untouched by JS, and then allow the script to assemble it into the tabbed container.

Take a look at the following example — it starts with the tab/pane content in dt/dd elements inside a dl, which displays just fine without JavaScript. When the JavaScript runs, it restructures the markup and then wires the interactivity (in a less contrived example you might execute both these steps in one fell swoop). Here it is without the JavaScript:

All the content is visible and the experience is fully usable for a user with JavaScript disabled. Below we have that same page but with the JavaScript executing to assemble the content into the tabbed interface and wire up the interactivity:

We now have an implementation that is fully accessible, fully keyboard navigable, and that provides a fully usable and accessible experience for users with JavaScript disabled!

Tools and References

As we discussed *way* back at the start of this article, two of the most important things when learning a new technical skill are:

  • Knowing where the best reference materials are (and how to navigate them), and
  • Knowing the appropriate tools for creation, debugging, etc.

ARIA is no exception. After a fair amount of futzing and fumbling when I first started learning ARIA, I’ve settled on the materials and tools that best enable me to get things done quickly.

For reference material:

  • The W3C WAI ARIA Practices Design Patterns and Widgets — This is my first click when trying to figure out how to build something with ARIA; I see if a similar interface is listed in this document, then read the requirements and, critically, review their example implementation, which can then be used as a reference/comparison for my own implementation.
  • MDN — A bit obvious, but for quick, human-readable references on specific ARIA attributes, as well as a collection of links back to the spec, MDN is hard to beat.

For debugging/testing:

  • The dev tools in both Chrome and Firefox have excellent tooling for interrogating the accessibility tree; I will often interrogate the components of an existing WAI example implementation and then my own implementation and make sure that I haven’t missed anything.
  • Both Chrome and Firefox also have automated accessibility audits built into the developer tools. These are not a complete, holistic replacement for proper review and testing by a knowledgeable and discerning eye, but they can be a decent initial check for obvious problems that can be identified programmatically.
  • Getting familiar with one or more screen readers and using them to navigate your document is probably the closest you can get to verifying you’ve set up your ARIA accessibility properly without either being a screen reader user yourself or user testing with users who primarily use a screen reader.
  • The truly excellent Testing-Library, created by Kent C. Dodds, is a testing library that strives to enable developers to write UI tests that mimic the way a user would interact with the site, with an emphasis on querying for UI with accessible queries that “reflect the experience of visual/mouse users as well as those that use assistive technology.” Adopting a library such as this can help you catch accessibility issues you may have missed during development.

In Conclusion…

Image of a chainsaw being used to cut a baguette
Those baguettes from the start of the article are probably super stale by now…

You have probably not become an expert in ARIA by reading this article. Since the author (me) is not an expert, it was unlikely there was any way that that would happen. However, you have hopefully gained an understanding of what ARIA can do, what references to use when building for ARIA, and how to understand how ARIA is impacting the accessibility of your site.

Remember that, while ARIA is an awesome tool, it is not a magic cure-all; it cannot resolve all your accessibility problems. Accessibility is many things, and ARIA is really intended for a narrow set of concerns: screen readers and keyboard-only users (and perhaps some other assistive technologies).

Try to get in the habit of considering accessibility as you develop (or even, better, before you start developing). Think about how your page might be able to be used by a person who only uses the keyboard, or can’t see the screen. Use the accessibility dev tools, test with a library like Testing Library that emphasizes accessibility, and try to get acquainted with navigating with the keyboard and a screen reader. Get in the habit of checking ARIA references for how to implement a feature; remember, in addition to providing attributes for roles, states, and properties, ARIA can also provide functionality like updating a user to changes or notifications with ARIA live regions.

If you have made it this far, thank you for reading this egregiously long article. If you enjoyed this read and would like to learn more about accessibility, consider starting at the beginning of this series. I hope you can take what you have learned here and begin to apply it to your work. Good luck, and happy coding!

Image of the logo for this series (a modified version of the accessible icon symbol, which is an image of an individual in a wheelchair moving forward quickly but with a power symbol added in the wheel) holding a baguette and wearing a beret; there is a speech bubble that indicates the individual is saying “au revoir!”




Alexander Nied

Chicago-based web application developer specializing in front end web development. Working at SPR as a senior consultant.