This document is in beta. Help us by reporting issues via Github or email
On this page:
The code should enable assistive technologies to understand the name, role and state of every interactive UI component.
Every user interface components that users can interact with should convey an ‘Accessible Name’, what type of component it is (for example “tab”, “switch” or “heading”), and its current state to assistive technologies.
Native elements (meaning elements that come out of the box in HTML, iOS and Android) generally provide roles/traits and properties by default. But custom-built elements will require all accessibility roles/traits and properties to be set.
Users of assistive technology, such as screen readers, rely on accessibility properties such as role, name, value, and state to be set appropriately in order to know how to identify and interact with an element or object.
Following this guidelines ensures that screen readers and speech-input software understand …
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)
Note: This success criterion is primarily for Web authors who develop or script their own user interface components. For example, standard HTML controls already meet this success criterion when used according to specification.
See the W3C’s detailed explanation of this guideline with techniques and examples.
This section needs more content. Contribute via Github or email.
This section needs more content. Contribute via Github or email.
Since the Android framework has baked-in accessibility in its default widgets, you should always try to extend these whenever possible. If a custom view is absolutely necessary, you need to make it accessible. If you don’t, a service like TalkBack will skip it entirely, badly degrading the experience for users.
Complex views that act as containers require special attention, since children need separate focus, clickable actions, etc.
Here are some APIs for making custom views accessible:
Flutter deals with assistive technologies like screen readers using the Semantics()
widget. For a quick introduction of the Semantics()
widget you can read this article.
##
If a widget does not have a ‘Accessible Name’ by default then use Semantics()
.
The Semantics()
widget has many properties for adding semantics that can be read by a screen reader but for a custom one use label
as shown below.
Semantics(
lable: String, // lable for a custom semantic name
child: // widget in need of semantics
)
Semantics()
widget has a lot of properties for affecting accessibility check the flutter documentation for a complete list or look go into the Semantics
class in your IDE.Every user interface components that users can interact with needs to have a name that assistive technologies (like screen readers or speech-input software) can understand.
That name is called the ‘Accessible Name’. (In the official Web Content Accessibility Guidelines, that name is just called ‘name’).
For example:
aria-label
for the Web for example).An interactive UI component might be given an Accessibility Name in a number of ways:
input
element with a label
element, or by using aria-labelledby
);aria-label="Search"
).<iframe>
elements<iframe>
element used on the page should include a title
attribute that accurately describes the frame content (e.g. “Travel form”).
<title>
element as a source for the iframe’s ‘Accessible Name’ on your page.<a>
or <button>
element contains no text content, and so has no accessible name;<label>
element, and so has no accessible name;<iframe>
element used in the source code of the page doesn’t include a title
attribute that accurately describes the frame content.Links, buttons and form fields should be implemented as native HTML controls (e.g. <a>
, <button>
, <input>
, <select>
), rather than as custom controls (e.g. using <div>
, <span>
elements and scripting that replicated the built-in behaviour of native HTML controls).
When standard HTML controls do not exist (and only then), use generic HTML elements and provide equivalents via ARIA and via a method that does not require ARIA.
Most HTML elements have an implied ‘role’, that communicate what type of component it is to Assistive Technologies. For example:
button
element has an implicit role of button
;a
element with an href
attribute has an implicit role of link
;li
element has an implicit role of listitem
;dd
element has an implicit role of definition
;some HTML elements like div
and span
do not convey any role to assistive technologies.
See the W3C ‘ARIA in HTML’ document to see the implicit roles of other HTML elements.
If incorrect HTML element was used to build a component, or if a div
or span
has been used where something more meaningful like a button
or a href="..."
should have been used, you can do two things:
Many common interactive components can be expressed with HTML alone. For example:
a
element with an href="..."
attributebutton
element or a input
element with type="button"
fieldset
, legend
and input type="radio"
elementsBut other very common interactive elements can’t be semantically expressed with HTML alone. For example:
tablist
, tab
and tabpanel
roles on top of ul
, li
, a
and div
or section
elements.dialog
element, but it’s not well supported. So, as of November 2019, if you want to build a modal dialog, you should use a div
and add role="dialog"
as well as aria-modal="true
. The button triggering the modal should have aria-haspopup="true"
.The HTML code of custom controls (e.g. sliders, tabs, accordions) should the right ARIA attributes to describe their role and status (e.g. tab, slider, selected, expanded, collapsed).
role
without implementing the keyboard support that is implied that by role (see example further below);<div>
or <span>
has been used as the basis for an interactive component, but ARIA role
has not been used to identify the purpose of the component (or its constituent parts);<ul>
, <li>
, and <a>
elements, but the ARIA role
attribute has not been used to provide the tablist
, tab
, and tabpanel
roles;<a>
element has been used as the basis for a button, but the ARIA button
role has not been applied.<!-- Example 1 - standard control -->
<input type="checkbox" id="c1" /><label for="c1">Remember me</label>
<!-- Example 2 - ARIA supported tree view with fall-back -->
<ul role="tree">
<li aria-level="0" aria-expanded="true" role="treeitem">
<a href="...">TV Shows <span class="offscrn"> - Expanded</span></a>
<ul>
<li aria-level="1" role="treeitem"><a href="...">Comedy</a></li>
<li aria-level="1" role="treeitem"><a href="...">Drama</a></li>
<li aria-level="1" role="treeitem"><a href="...">Sports</a></li>
</ul>
</li>
<li aria-level="0" aria-expanded="true" role="treeitem">
<a href="...">Radio Shows <span class="offscrn"> - Expanded</span></a>
<ul>
<li aria-level="1" role="treeitem"><a href="...">News</a></li>
<li aria-level="1" role="treeitem"><a href="...">Soap</a></li>
<li aria-level="1" role="treeitem"><a href="...">Sports</a></li>
</ul>
</li>
</ul>
<!-- Don't do this -->
<!-- Example 1 - non-standard control -->
<div><img src="chkbx" alt="checkbox" />Remember me</div>
<!-- Example 2 - inaccessible tree view -->
<div>
<div onClick="toggle();">
TV Shows
<div>
<div class="indent">Comedy</div>
<div class="indent">Drama</div>
<div class="indent">Sports</div>
</div>
</div>
<div onclick="toggle();">
Radio Shows
<div>
<div class="indent">News</div>
<div class="indent">Soap</div>
<div class="indent">Sports</div>
</div>
</div>
</div>
If you ARIA’s role
property to create components that HTML alone can’t express, you will often need to use aria-
attributes to express the properties and states of those components. For example:
aria-selected
to express whether a li role="tab"
element is the tab that is currently active within its ul role="tablist"
parent.aria-expanded
to express whether a component that opens and closes is currently expanded.aria-checked
to express the state of switch component you’ve built with button role="switch"
The HTML code of custom controls (e.g. sliders, tabs, accordions) should the right ARIA attributes to describe their role and status (e.g. tab, slider, selected, expanded, collapsed).
aria-expanded
attribute has not been used to communicate the disclosure component’s current state;role
is just a promise. You need to implement the keyboard support yourselfThe role
and aria-
only tell Assistive Technologies how to announce a component to screen reader users. The keyboard interactions that are implied by different ARIA role
s are still for you to implement.
For example, let’s imagine that you’re building a button using div role="button"
, rather than using the native HTML button
or input type="button"
elements:
role="button"
implies that this component is a button. Buttons can be activated using the ‘Enter’ and ‘Space’ keys. You will need to implement responses to these key presses yourself.div role="button"
doesn’t automatically place that pseudo-button in the page’s tab order, which means that users couldn’t reach it using the Tab
key. You’d need to remember to add that yourself too, by adding the tabindex="0"
attribute.
Note: it’s much better to use button
or input type="button"
as they come with keyboard support built-in.
Look at the W3C ARIA in HTML document to see:
Read the W3C Using ARIA document to know the “5 rules of ARIA” and understand a bit more about ARIA before creating custom components with ARIA.
The ARIA 1.1 specification document has a lot of information about how to use each ARIA role
and aria-
attributes.
The ARIA Authoring Practices Guide 1.1 is a great document that tells you how to implement a broad range of very common UI patterns (e.g. tabs, switches, toggles, dialog, feed, etc) with lots of details and working examples. It tells you:
iframes
specificallyThis document is in beta. Help us by reporting issues via Github or email