What is ARIA?

WAI-ARIA is the Web Accessibility Initiative - Accessible Rich Internet Applications. These are guidelines that help you develop accessible interactive and dynamic applications. The term rich internet applications means apps that have interactivity, dynamic data, or other similar characteristics. These pages are not just a static pages with content that doesn't change and content you can't interact with.

ARIA allows you to make a page accessible when HTML can't. For example, you can use semantic elements to help add meaning when someone is reading your page with a screen reader, but there aren't semantic elements for everything. You can use ARIA to make a non-semantic element more semantic.

ARIA also allows you to add “regions” to a page, to make it easier for users that use keyboard navigation (visual, motor) to navigate more efficiently. Additionally, you can make visual feedback easier for visual/cognitive by adding ARIA states and properties, for example showing a form field is invalid by making it red is not understood by users who can't see red, or can't see at all, or users with cognitive issues that have trouble understanding colour feedback.

What's in ARIA?

ARIA consists of attributes and values you add to existing elements to make those elements and their content more accessible. ARIA attributes consist of roles, properties, and states.

Roles, Properties, States

Roles

Most HTML elements have a default role e.g. <nav> is "navigation" and <button> is "button". Roles help define what an element is used for, what it does in the page/app. ARIA can define roles that HTML doesn't have elements for. A very common example is role="search": there is no <search> element in HTML, but often screen reader users want to jump straight to the search form on a page (many sites these days have little search forms somewhere on the page). You can use <form role=”search” ….> for your search form. This makes it easier for a screen reader user or keyboard user to navigate quickly to the search form on the page (instead of, well, searching for it by tabbing all over the page).

ARIA can allow you to use the role="" attribute to change the role of an element (but you shouldn't do that unless you have to, see Rule #1 below). You might have a small social media icon you want to use as a button, so you could say <img role="button">, that way it's treated like a button by keyboard navigation and screen readers.

Note that you shouldn't be be redundant e.g. <button role="button"> is unnecessary and wasteful.

Properties

Properties allow you to add semantics or information to an existing HTML element, where that information isn't already part of HTML. For example: when creating HTML forms, it's common to make an input field a "required field" by adding the required HTML attribute:

<input type="text" name="username" required>

Often CSS is used to show visually that the item is required, such as adding a yellow background or red border, or perhaps a small icon. Screen reader users don't see these visual cues. The aria-required attribute is used by screen readers to announce to the user that the field is required.

States

States are the current circumstances or conditions of an element: Does it have the focus? Does an input field contain an invalid value? States are visual: invalid fields might be styled differently with CSS than fields that contain valid values. Screen readers can't "see" states and need a way to announce/convey an element's state to the user. For example, aria-invalid, when true, tells the screen reader to announce that a field contains an invalid input value.

Regions

A typical page has regions e.g. header, footer, main content, navigation, sidebar, etc.

Landmarks are places you can land via keyboard navigation or screen reader navigation. Obvious landmarks are links, buttons, form fields, etc but regions are also landmarks.

This provides much easier and efficient navigation for keyboard users and screen readers, for example it allows a user to skip a repetitive header and jump to the main content quickly. A user could also jump directly to a document's footer where you usually find contact links/info. A user might want to stop what they're doing and jump to the topic menu on a page.

All of these things are easy for visual users! But for other users, these tasks could be cumbersome without some help. Thanksfully, screen readers give their users a list of all landmarks on a page for easy navigation.

ARIA has some roles that can be used to define regions of a page. These roles are called Landmark Roles. They include:

  • banner - this typically represents the header area of a document
  • navigation - for navigation areas
  • main - for main content area
  • complementary - used for content that's related to the main content, like something you'd put in an <aside> element
  • contentinfo - used for the footer area, usually
  • search - for the area that contains a search form or related functionality

Most of these landmark roles exist as HTML elements such as <header> (banner), <nav> (navigation), etc. Use landmark roles when you need additional landmarks that aren't already provided by existing semantic region elements.

The Five Rules of ARIA

There are five rules you should follow when using ARIA. The common saying is It's better to have NO ARIA than BAD ARIA.

  1. If you can use an HTML element/attribute with the semantics/behaviour you need, do it.
    • Don't just re-purpose an element and change its ARIA role. For example, if you want a bit of complementary content to be fully indented on both the right and left, don't just stick it in a <blockquote role="complementary">. The <blockquote> is for long quotes, not for complementary content. Instead, use an <aside> element and CSS margins and padding to give it the appearance you want. The whole point of an <aside> is to add complementary content; it already has the role of "complementary", so use this instead. The rest is just formatting.
    • Exceptions:
      • a particular element can't be styled the way you need to with the current design restrictions, so you need to use a different element
      • there is no HTML element that supports the accessibility feature you want, so you have to use something else (e.g. before we had <progress>, you would make a progress bar out of a <div></div>
      • the accessibility feature you want is not implemented in HTML e.g. you want to use the <meter> element but it's not completely accessible in all browsers, so you might make something similar out of another, more accessible element
  2. Do not change an element's semantics unless it's absolutely necessary.
    • Don't use an element for something it's not intended for. For example, a <ul> is read by screen readers as a list of items a certain way: the screen reader announces how many items are in the list, for example. Lists are also navigated a certain way via the keyboard. If you make a <ul> your page navigation by adding role="navigation", it becomes a navigation object, which is read out differently and accessed differently via keyboard. This can be confusing to users and makes keyboard navigation inconsistent and difficult in some cases. Instead, use
      <nav>
        <ul> ... </ul>
      </nav>
      or use
      <div role="navigation">
        <ul> ... </ul>
      </div>
    • This becomes important when you're taking a typically non-interactive element and turning it into an interactive element. For example, say you want an <img> to behave like a button by adding role="button". This is acceptable since adding role="button" makes the <img> a button to someone who's using a screen reader or keyboard navigation.
  3. All interactive ARIA elements must be usable with a keyboard.
    • ARIA has specific keyboard functionality for elements, and specific rules about how elements should be used, what roles they should have etc. These are These are ARIA Design Patterns (opens in the ref tab/window). For example, buttons are navigated using the tab key to receive the focus, they are activated while having the focus by pressing SPACE key or ENTER key.
    • If you create your own custom widget, it should be navigable and functional via keyboard using the standard ARIA design patterns
  4. Interactive elements that are focusable should never be hidden by adding role="presentation" or aria-hidden="true".
    • role="presentation" removes the semantics from an element, it removes the element's "meaning" and turns its content into plain text. For example, using <a role="presentation"></a> makes the link element no longer a focusable/interactive element to a screen reader. It's still in the DOM and still in the accessibility tree, but now it's plain text in the accessibility tree. The screen reader will not treat it functionally like a link.
      • A good use of role="presentation" would be to hide a decorative image from a screen reader: screen reader users don't care about decorations, but these kinds of images need to be part of the DOM for the page's appearance and layout.
      • Applying role="presentation" to an interactive element doesn't do anything, so adding it is pointless.
    • aria-hidden="true" hides an element from screen readers and keyboard navigation: it removes the element from the accessibility tree entirely.
      • A good use of aria-hidden="true" would be to hide a container of off-screen content from the screen reader: Screen readers can read all the content that's visible, even if it's visually off-screen. You might put content off-screen for visual users so that it can appear when the user clicks on a button. In this case, you need to hide the off-screen content from the screen reader using aria-hidden="true". You can then set aria-hidden="false" in JavaScript when the user triggers the action that shows the content.
      • Adding aria-hidden="true" to an interactive element removes the semantics from the element and leaves it in the accessibility tree. This means the user can tab to the element but the screen reader doesn't tell the user what the object. The user might assume something is wrong with their screen reader, something wrong with the page, or they would simply be confused and not know what to do with the item they just tabbed to.
  5. All interactive elements must have an accessible name.
    • The name of an element is usually the text or caption. For example, a link's text, a button's caption, a form input's label, etc.
    • When a screen reader encounters an interactive element, it will read out the name of the element. A common example of bad naming is when people want to make a link and they say something like:
      <p>Read more about accessible web
        design <a href="http://webaim.org">here</a>.</p>
      When the user tabs through the links on the page, they get to that one and the screen reader says "here". Imagine how useless that is!
    • Another really common example:
      Enter Name: <input type="text" name="input" id="input">
      <button>Click Here</button>
      <!-- or instead: -->
      <input type="Submit">
      • First problem: the input is lacking an accessible label, so when a user tabs to this field, the screen reader just says "input field", "edit" or something similar and equally uninformative. Note that using placeholder="enter name" is not supported in most screen readers, so you can't use that as a fallback.
      • Second problem: the button's name/caption is not descriptive: click me for what? Are we logging in, registering, signing away our first born? A sighted user can tell by looking at surrounding content, but a screen reader user that is tabbing from control to control may not. Also, a screen reader presents the user with a list of landmarks that they can navigate to with the keyboard: when listening to such a list, "Click Me" isn't informative.
      • Third problem: has a visual caption (by default it's "Submit") but the accessibility tree doesn't always make note of that. If you were to check this with WAVE, it would alert you with a warning that the Submit button doesn't have an accessible name.
      A better version:
      <p>Read more about accessible web
        design at <a href="http://webaim.org">WebAIM.org's web site</a>.</p>
      
      <label for="input">Enter Name:
        <input type="text" name="input" id="input">
      </label>
      <button>Generate Pirate Name</button>
      <!-- or instead: -->
      <input type="Submit" value="Submit">