Use SPACEBAR to move forward through slides.
SPACEBAR to move forward through slides.
SHIFT & SPACEBAR to move backwards through slides.
LEFT ARROW & RIGHT ARROW to move through sections.
ESC to see overview and ESC again to exit.
F to enter presentation mode and ESC to exit.
aria-describedby
, aria-labelledby
and aria-label
.Accessibility APIs communicate information about the user interface from the browser to the Assistive Technology.
There have been many Accessibility APIs released over the years, all building on and improving previous versions.
Year | API | Who | For |
---|---|---|---|
1997 | Microsoft Active Accessibility (MSAA) | Microsoft | Windows 95 |
1998 | IAccessible | IBM/Sun | Cross platform |
2001 | Assistive Technology Service Provider Interface (AT-SPI) | Linux | Linux OS |
2002 | NSAccessibility | Apple | Mac OS 10.2 |
2007 | User Interface Automation (UIA) | Microsoft | Windows 7 |
2007 | IAccessible2 | IBM | Windows and Linux |
2009 | UI Accessibility API | Apple | iOS 3 |
Browsers generally support one or more of the available accessibility APIs for the platform they’re running on.
The browser uses the DOM, along with further information derived from CSS, to generate an Accessibility Tree.
This information is passed to the relevant accessibility APIs associated with the browser / operating system.
This Accessibility Tree exposes information on specific elements to Assistive Technologies via the Accessibility API.
Information includes:
Each browser will produce a unique Accessibility Tree due to their specific source code/Accessibility API combination.
Chrome’s “Accessibility” tab has three key areas:
As you inspect an element in the DOM, any relevant ARIA information is presented in the Accessibility Tree tab.
As you inspect an element in the DOM, any relevant ARIA attributes are presented in the ARIA Attributes tab.
As you inspect an element in the DOM, all the computed properties of that element are presented in the Computed Properties tab.
Browsers use the DOM tree to create a second tree, called the Accessibility Tree.
Inspect the “What are mammals?” heading. What is this elements role
and level
the Accessibility Tree?
Inspect the “Full name” <input>
. What is this elements role
in the Accessibility Tree?
Inspect the “Email” <input>
. Is this element defined as being required
in the Accessibility Tree?
Type some content into the “Email” <input>
field. Does the element now have a value
in the Accessibility Tree?
Choose “Aardvark” from the “Favourite Mammal” dropdown. Does the <select>
element now have a value
in the Accessibility Tree?
Check “Yes” from the “Subscribe to newsletter” checkbox group. Does the checkbox now have a checked
status in the Accessibility Tree?
As you can see, there are a wide range of possible properties that can be presented as part of the accessibility tree, depending on the element being inspected.
Some of the key accessibility tree properties include:
Name: [ accessible name as a text string ]
Role: [ pre-defined list of roles ]
Description: [ description as a text string ]
Value: [ current value as a text string ]
Required: true | false
Expanded: true | false
Checked: true | false
Disabled: true | false
Described by: [ element][#id][.class ]
Labeled by: [ element][#id][.class ]
Accessible names are names given to elements in the Accessibility tree.
Accessible names are very important for Assistive Technology users as they help to identify elements within the accessibility tree.
Accessible names are defined as text strings.
Chrome’s accessibility tree shows all the possible options that could be used to provide the accessible name.
It also displays the final computed accessible name as a text string.
Accessible names can be applied to elements in a range of different ways, depending on the element.
The contents of links and buttons can be converted into text strings and used as their accessible names.
<a href="#">Content</a>
<button>Content</button>
The value of the alt
attribute for an image can be converted into a text string and used as the accessible name.
<img src="ball.jpg" alt="Content">
For elements that allow the title
attribute, the title
value can be converted into a text string and used as the accessible name.
<button title="Content"></button>
For some elements, the placeholder
value can be converted into a text string and used as the accessible name.
<input type="text" placeholder="Content">
For some elements, the aria-label
value can be converted into a text string and used as the accessible name.
<button aria-label="Content"></button>
The contents of the <label>
element can be converted into a text string and used as the accessible name for <input>
, <select>
and <textarea>
elements.
<label for="name">Content</label>
<input id="name" type="text">
The contents of the <caption>
element can be converted into a text string and used as the accessible name for the <table>
element.
<table>
<caption>Content</caption>
</table>
The value of aria-labelledby
attribute can be converted into a text string and used as the accessible name for various elements.
<div aria-labelledby="heading">
<h2 id="heading">Content</h2>
</div>
<a>
and <button>
elements.<label>
contents for relevant form elements.<caption>
contents for <table>
elements.<img>
elements.placeholder
.title
.aria-label
.aria-labelledby
.Inspect the “Email” <input>
. What is this elements name in the Accessibility Tree?
In this case, the accessible name is taken from the for
attribute of the <label>
element.
In the DOM, remove for="form-email"
from the “Email” <label>
element. Does the element have a name in the Accessibility Tree now?
This form field now has no accessible name, so there is no way for Assistive Technologies to understand its purpose.
Inspect the <fieldset>
element associated with “Subscribe to newsletter”. Does it have a name in the Accessibility Tree?
Inspect the <main>
element above the “What are mammals” heading. Does it have a name in the Accessibility Tree?
Look at the first “Find out more” link on the page. In theory, the accessible name for this element should be “Find out more” from the contents of the link.
However, the element has also been given an aria-label
, which provides a different accessible name of “Find out more about mammals”.
So, there are two possible accessible names. Which one wins? The answer is displayed in the accessibility tree.
Notice how the accessibility tree interface displays the link contents as crossed out, while the aria-label
content is highlighted.
This means the aria-label
content will be used as the accessible name for this element.
An accessible description provides additional information, related to an interface element, that complements the accessible name.
The accessible description might or might not be presented visually on-screen.
Accessible descriptions are defined as text strings.
Inspect the “Address” input. What is this elements description
in the Accessibility Tree?
How are the accessible name and description announced in different screen readers?
Screen readers announce objects within the accessibility tree in the following order:
let’s use the “Address” <input>
again to see the announcement order in different screen readers.
With Voiceover, there is a pause after the accessible name and role are announced.
WAI is a working group that develops standards and support materials to help implement accessibility.
ARIA is a standard that defines a way to make websites and web apps more accessible to people with disabilities.
ARIA especially helps with dynamic content and advanced user interface controls developed with HTML and JavaScript.
WAI-ARIA 1.0 was published as a completed W3C Recommendation on 20 March 2014.
WAI-ARIA 1.1 was published as a completed W3C Recommendation on 14 December 2017.
WAI-ARIA 1.2 was published as a completed W3C Working Draft 18 December 2019. This means it is still not the official standard yet!
How ARIA works can be defined in three simple statements:
ARIA can be used change and augment the Accessibility Tree in the following ways:
i.e. adding semantics to generic elements via the role attribute.
<div role="button"></div>
i.e. modifying the existing semantics of elements via the role attribute.
<button role="tab"></button>
i.e. informing Assistive Technologies of a widget’s current state.
<button aria-expanded="true"></button>
i.e. adding additional labelling to elements.
<button aria-label="Close modal"></button>
i.e. adding descriptions to elements.
<input type="text" aria-describedby="a1">
<span id="a1">Error message</span>
i.e. informing Assistive Technologies of the relationships between specific elements, than may not be possible via the DOM.
<button role="tab" aria-controls="a1"></button>
<div role="tabpanel" id="a1"></div>
i.e. Defining region “live” and may change.
<div aria-live="polite"></div>
ARIA attributes are broken down into three categories:
ARIA roles are HTML attributes that are added to elements using:
role="[role-type]"
.
ARIA roles can be used to add or change the semantic meaning of HTML elements in the accessibility tree.
For example: Is the element a menu, slider, spinner, progress bar?
<div role="tabpanel"></div>
A list of all roles, including how they have changed in different versions of ARIA.
ARIA state and properties are HTML attributes that are added to elements using:
aria-[state|property]=[property-type]
ARIA states define the current state of HTML elements in the accessibility tree.
For example: Is the element checked or disabled?
<input aria-disabled="true" type="text">
ARIA properties define purpose or relationships of HTML elements in the accessibility tree.
For example: "Does the element have a description? Does the element interact with other elements?
<input aria-describedby="format">
<span id="format">(mm/dd/yyyy)</span>
A list of all states and properties, including how they have changed in different versions of ARIA.
role="checkbox"
to each of the fake checkboxes.aria-checked="false"
to each of the fake checkboxes.role="group"
to the parent container.aria-labelledby="group-label"
to the parent container .id="group-label"
to the <h3>
element.Imagine you have to make a checkbox group, but you have to to use <div>
elements instead of native checkboxes.
As you will see:
tabindex="0"
.However, this widget is completely inaccessible to assistive technologies.
<h3>
heading is not programmatically associated with the checkbox group.Add role="checkbox"
to each of the fake checkboxes.
<div
class="checkbox"
tabindex="0"
role="checkbox"
>
Lettuce
</div>
<div
class="checkbox"
tabindex="0"
role="checkbox"
>
Tomato
</div>
<div
class="checkbox"
tabindex="0"
role="checkbox"
>
Mustard
</div>
aria-checked="true"
to the first fake checkbox.aria-checked="false"
to other fake checkboxes.<div
class="checkbox"
tabindex="0"
role="checkbox"
aria-checked="true"
>
Lettuce
</div>
<div
class="checkbox"
tabindex="0"
role="checkbox"
aria-checked="false"
>
Tomato
</div>
<div
class="checkbox"
tabindex="0"
role="checkbox"
aria-checked="false"
>
Mustard
</div>
If we inspect any of the fake checkboxes in the accessibility tree, they now have roles and states.
Add role="group"
to the parent container so that we can create a fake <fieldset>
.
<div
role="group"
>
</div>
Add aria-labelledby="group-label"
to the parent container so we can give it an accessible name.
<div
role="group"
aria-labelledby="group-label"
>
</div>
Add id="group-label"
to the <h3>
element. Now it will operate like a fake <legend>
.
<h3 id="group-label">Choose some toppings</h3>
If we inspect the parent container in the accessibility tree, it now has an accessible name and a role.
This is a quick example to show how ARIA is used to augment the accessibility tree to help Assistive Technologies.
This is where a primary element is given a label (another name for an accessible name) by a secondary element.
The aria-labelledby
attribute is applied to the primary element, and the matching ID value is applied to the secondary element.
So, the primary element is literally being “labelled by” the secondary element in the accessibility tree.
<section aria-labelledby="section-heading">
<h3 id="section-heading">Contact details</h3>
</section>
This <section>
element will now have an accessible name of “Contact details” in the accessibility tree because it is being “labelled by” the <h3>
element.
aria-labelledby="section-heading"
the the <div>
.id="section-heading"
to the <h3>
.<!-- Before -->
<section>
<h3>Contact details</h3>
</section>
<!-- Step 1: add aria-labelledby -->
<section aria-labelledby="section-heading">
<h3>Contact details</h3>
</section>
<!-- Step 2: add id -->
<section aria-labelledby="section-heading">
<h3 id="section-heading">Contact details</h3>
</section>
The aria-label
attribute is used to provide a label directly to the element itself.
The primary element is literally being “given a label” in the accessibility tree.
<button
type="button"
aria-label="Close and return to account details"
>
Close
</button>
This <button>
element will now have an accessible name of “Close and return to account details” in the accessibility tree.
In fact, if you look in the accessibility tree, the contents of the <button>
is replaced by the aria-label
as the accessible name.
aria-label="Close and return to account details"
the the <button>
.<!-- Before -->
<button
class="button"
type="button"
>
Close
</button>
<!-- Step 1: Add aria-label -->
<button
class="button"
type="button"
aria-label="Close and return to account details"
>
Close
</button>
This is where a primary element is given a description by a secondary element.
The aria-describedby
attribute is applied to the primary element, and the matching ID
value is applied to the secondary element.
So, the primary element is literally being “described by” the secondary element in the accessibility tree.
<label for="a">Phone</label>
<input id="a" type="text" aria-describedby="i1">
<p id="i1">Error: Include area code</p>
This <input>
element already has an accessible name of “Phone”.
However, it will now has an accessible description of “Error: Include area code” in the accessibility tree.
The aria-describedby
attribute cannot provide an accessible name in the accessibility tree - it is just for descriptions.
Multiple descriptions can be applied to a single element using aria-describedby
. They are defined using space-separated values.
<label for="a">Phone</label>
<p id="hint1">Include an area code</p>
<input id="a" type="text" aria-describedby="hint1 error1">
<p id="error1">Error: Include area code</p>
The order that these elements are defined within the aria-describedby value determines the order in which the descriptions are announced.
In this case, because hint1
is defined before error1
the accessible description will be:
“Include an area code Error: Include area code”
id="hint"
to the <span>
element with a class of help-text
.id="error"
to the <span>
element with a class of error-message
.aria-describedby="hint error"
to the <input>
element.<!-- Before -->
<label class="label" for="b">Phone</label>
<span class="help-text">
Include area code
</span>
<input
class="input"
id="b"
type="text"
>
<span class="error-message">
Error: Include area code
</span>
<!-- Step 1: add id to help-text span -->
<label class="label" for="b">Phone</label>
<span class="help-text" id="hint">
Include area code
</span>
<input
class="input"
id="b"
type="text"
>
<span class="error-message">
Error: Include area code
</span>
<!-- Step 2: add id to error-message span -->
<label class="label" for="b">Phone</label>
<span class="help-text" id="hint">
Include area code
</span>
<input
class="input"
id="b"
type="text"
>
<span class="error-message" id="error">
Error: Include area code
</span>
<!-- Step 3: add aria-describedby -->
<label class="label" for="b">Phone</label>
<span class="help-text" id="hint">
Include area code
</span>
<input
class="input"
id="b"
type="text"
aria-describedby="hint error"
>
<span class="error-message" id="error">
Error: Include area code
</span>