Basics
- All content on a webpage should be contained inside HTML regions (or ARIA landmark roles).
- Use ARIA roles to describe the type of widget presented.
- Use an aria-label attribute to identify form controls that don't have a label.
- Use tabindex to ensure an element can receive keyboard focus.
- Alert users to dynamic changes in content by defining live regions, especially error messages.
- Use ARIA states to describe the state widgets are in.
In-depth
The Web Accessibility Initiative (WAI) defines Accessible Rich Internet Applications (ARIA) as:
a way to make Web content and Web applications more accessible to people with disabilities. It especially helps with dynamic content and advanced user interface controls developed with Ajax, HTML, JavaScript, and related technologies.
Most HTML elements have a default role that browsers and assistive devices understand. A button has the role of button, for instance. Some have additional properties and states as well--for example, a link can be active or visited. But many elements, such as divs and spans, don't have a role.
ARIA allows developers to define roles, states and properties for elements that are not natively available in HTML and to override the HTML defaults of elements. ARIA is supported by most browsers and screen readers, and it is a powerful tool in a developer's accessibility arsenal.
HTML5 regions and ARIA landmark roles
Landmarks and regions identify the major structural parts of a webpage and are used by screen reader and others for keyboard navigation. All content on a webpage must be contained inside landmarks/regions.
There are two ways to define landmarks/regions: with an HTML5 region element or an ARIA landmark role. For a long time, some elements and roles weren't universally supported, so developers were recommended to use both. However, this is no longer the case.
Use an HTML region if possible. When that isn't possible, add an ARIA landmark role to the element instead.
HTML5 region element | ARIA landmark role | Definition | Usage |
---|
<header> | role="banner" | Site-oriented content at the beginning of each page | Only one per page. Must be a top-level landmark. |
<nav> | role="navigation" | Groups of links intended for website or page navigation | If more than one, each should have a unique label. |
<main> | role="main" | Primary content | Only one per page. Must be a top-level landmark. |
<section> | role="region" | Content relevant to a specific, author-specified purpose | Must have an unique label. |
<aside> | role="complementary" | Supporting section that complements and is related to the main content but remains meaningful when separated from it | Must be a top-level landmark. If more than one, each should have an unique label. |
<footer> | role="contentinfo" | Common information at the bottom of each page | Only one per page. Must be a top-level landmark. |
<form> | role="form" | Collection of items and objects that together create a form | Must have an unique label. |
None | role="search" | Contains search functionality for the site | If more than one, each should have an unique label. |
HTML regions
<header> ... </header>
<nav> ... </nav>
<main> ... </main>
<footer> ... </footer>
Equivalent ARIA landmark roles
<div role="banner"> ... </div>
<div role="navigation"> ... </div>
<div role="main"> ... </div>
<div role="contentinfo"> ... </div>
Labels for HTML5 and ARIA landmarks
Some HTML5 regions/ARIA landmarks require labels.
- The <header>, <main> and <footer> landmarks do not need labels because they can only be defined once per page.
- Landmarks such as <form> and <section> must always be labeled, even when they are the only landmark of that type on the page.
- Landmarks such as <nav> and <aside> must have a unique label if more than one is used per page.
You can give landmarks (and other elements) unique labels using the aria-label and aria-labelledby attributes.
aria-label: Provides text that labels the current landmark when no other label exists.
<aside aria-label="Title for Complementary Area 1">
...
</aside>
aria-labelledby: Identifies an element somewhere else on the page that labels the current landmark.
<aside aria-labelledby="comp1">
<h2 id="comp1">Title for Complementary Area 1</h2>
...
</aside>
Drawbacks of aria-label and aria-labelledby are that they are only visible to assistive technologies (they're not available to people who use the visual display), and they cannot be translated.
ARIA roles to describe widgets
ARIA roles can be used to define generic HTML5 elements, such as divs and spans. Giving an element a role provides assistive technologies with information about how to handle each element. For example, the following seems to be a simple list:
<ul>
<li><a href="#bio">Bio</a></li>
<li><a href="#resume">Resume</a></li>
<li><a href="#awards">Awards</a></li>
</ul>
But it could be intended to represent tabs or a menu, both of which function quite differently. In the absence of visual cues, adding ARIA roles defines elements so assistive devices and users know how those elements should behave.
<ul role="tablist">
<li><a role="tab" href="#bio">Bio</a></li>
Live regions for dynamic content
For small chunks of plain text content that changes dynamically without page reload, such as error messages or page warnings, ARIA provides a way to alert assistive device users of those changes: the aria-live property.
<select>
<option> .... </option>
</select>
<div aria-live="polite">
...
</div>
Possible values for aria-live are:
- off: is the default and the screen reader will not announce the changes unless the users focuses on the region
- polite: changes will be announced when the user pauses next
- assertive: changes are immediately announced
aria-live="assertive"
is often used for dynamic error messages and is equivalent to role="alert"
.
Tabindex and ARIA roles to set focus
An important component of keyboard accessibility is the ability to set focus on an element. By default in HTML, only links, buttons and forms receive focus. NOTE: An anchor with an empty HREF (an "empty link") is not focusable or keyboard accessible (see more in Javascript).
Tabindex to make elements focusable
Setting tabindex="0"
on an element places the element in the sequential navigation flow of the document and allows it to receive focus. For instance, tabindex will allow focus to be set on a normally unfocusable element, such as a <div>:
<div id="menu-container" tabindex="0">
ARIA states
ARIA provides for many states that can add, supplement or alter the current condition of an HTML5 element. For example:
<input aria-disabled="true">
<input aria-required="false">
<input aria-hidden="true">
<input aria-checked="false">
There are many aria states and properties to enhance the accessibility of HTML5 elements. See a list of all ARIA properties and states.
Resources
An excellent resource for learning ARIA is the Ryerson University online textbook, Web Accessibility for Developers.
For a table of ARIA roles and attributes, see the ARIA Role Matrices from WhatSock.
The A11y Project is a good source for accessible widgets. Additionally, the "Design Patterns and Widgets" section of the WAI-ARIA Authoring Practices 1.1 provides extensive documentation on creating accessible Javascript widgets, such as:
- Accordion
- Alert and Message Dialogs
- Breadcrumb
- Button
- Checkbox
- Combo Box
- Dialog (Modal and non-modal)
- Grids
- Link
- Listbox
- Menu or Menu bar
- Menu Button
- Radio Group
- Slider
- Spinbutton
- Table
- Tabs
- Toolbar
- Tree View
- Window Splitter
For more information on WAI-ARIA, see:
Relevant W3C WAI documents
- WCAG 2.1 Guideline 1.3.1 Info and Relationships: Information, structure, and relationships conveyed through presentation can be programmatically determined or are available in text.
- How to Meet WCAG 2.1 Guideline 1.3.1
- WCAG 2.1 Guideline 2.1.1 Keyboard: All functionality of the content is operable through a keyboard interface without requiring specific timings for individual keystrokes, except where the underlying function requires input that depends on the path of the user's movement and not just the endpoints.
- How to Meet WCAG 2.1 Guideline 2.1.1
- WCAG 2.1 Guideline 2.4.1 Bypass Blocks: A mechanism is available to bypass blocks of content that are repeated on multiple Web pages.
- How to Meet WCAG 2.1 Guideline 2.4.1
- WCAG 2.1 Guideline 2.4.4 Link Purpose (In Context): The purpose of each link can be determined from the link text alone or from the link text together with its programmatically determined link context, except where the purpose of the link would be ambiguous to users in general.
- How to Meet WCAG 2.1 Guideline 2.4.4
- WCAG 2.1 Guideline 3.3.1 — If an input error is automatically detected, the item that is in error is identified and the error is described to the user in text.
- How to Meet WCAG 2.1 Guideline 3.3.1
- WCAG 2.1 Guideline 3.3.2 — Labels or instructions are provided when content requires user input. (Level A)
- How to Meet WCAG 2.1 Guideline 3.3.2
- WCAG 2.1 Guideline 3.3.3 Error Suggestion: If an input error is automatically detected and suggestions for correction are known, then the suggestions are provided to the user, unless it would jeopardize the security or purpose of the content.
- How to Meet WCAG 2.1 Guideline 3.3.3
- WCAG 2.1 Guideline 4.1.2 — Name, Role, Value: For all user interface components (including but not limited to: form elements, links and components generated by scripts), the name and role can be programmatically determined; states, properties, and values that can be set by the user can be programmatically set; and notification of changes to these items is available to user agents, including assistive technologies. (Level A)
- How to Meet WCAG 2.1 Guideline 4.1.2