-
Notifications
You must be signed in to change notification settings - Fork 378
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Guideline for live regions #1027
Changes from all commits
bef47fb
f31d6ea
247f576
c67c3b8
828bddb
7e48d4d
83dd326
4c1b1aa
e788ca2
5b6adc4
d769a55
4be527c
6678012
27b2c17
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -1024,7 +1024,7 @@ <h4>WAI-ARIA Roles, States, and Properties</h4> | |||||
<li>The element that serves as an input and displays the combobox value has role <a href="#combobox" class="role-reference">combobox</a>.</li> | ||||||
<li> | ||||||
The combobox element has <a href="#aria-controls" class="property-reference">aria-controls</a> set to a value that refers to the element that serves as the popup. | ||||||
Note that <code>aria-controls</code> only needs to be set when the popup is visible. However, it is valid to reference an element that is not visible. | ||||||
Note that <code>aria-controls</code> only needs to be set when the popup is visible. However, it is valid to reference an element that is not visible. | ||||||
</li> | ||||||
<li>The popup is an element that has role <a href="#listbox" class="role-reference">listbox</a>, <a href="#tree" class="role-reference">tree</a>, <a href="#grid" class="role-reference">grid</a>, or <a href="#dialog" class="role-reference">dialog</a>.</li> | ||||||
<li> | ||||||
|
@@ -3734,6 +3734,390 @@ <h5>Examples</h5> | |||||
</section> | ||||||
</section> | ||||||
|
||||||
<section id="live_regions"> | ||||||
<h2>Live Regions</h2> | ||||||
|
||||||
<p> | ||||||
Live regions are perceivable regions of a web page that are typically updated as a result of an external event when user focus might be elsewhere. | ||||||
These regions are not always updated as a result of a user interaction. | ||||||
By marking such elements as live regions, users of assistive technology can be informed of the updated content automatically. | ||||||
</p> | ||||||
|
||||||
<p> | ||||||
Examples of live regions are a chat log and an error message. | ||||||
However, different kinds of live regions have different expected behavior; | ||||||
users might expect an error message to disrupt what they are doing, since the error is important, | ||||||
but want to wait with reading new chat messages until they are done typing their own message. | ||||||
</p> | ||||||
|
||||||
<section id="live_region_states_and_properties"> | ||||||
<h3>Live Region States and Properties</h3> | ||||||
|
||||||
<p> | ||||||
ARIA has the following attributes mark up live regions. | ||||||
</p> | ||||||
|
||||||
<table> | ||||||
<thead> | ||||||
<tr> | ||||||
<th>State/property</th> | ||||||
<th>Description</th> | ||||||
</tr> | ||||||
</thead> | ||||||
<tbody> | ||||||
<tr> | ||||||
<td><code>aria-live</code></td> | ||||||
<td>Enables a live region.</td> | ||||||
</tr> | ||||||
<tr> | ||||||
<td><code>aria-atomic</code></td> | ||||||
<td>Indicates what content to announce.</td> | ||||||
</tr> | ||||||
<tr> | ||||||
<td><code>aria-relevant</code></td> | ||||||
<td>Indicates which content changes are relevant.</td> | ||||||
</tr> | ||||||
<tr> | ||||||
<td><code>aria-busy</code></td> | ||||||
<td>Defers content updates. Not specific to live regions. See the <a href="#aria-busy">next section</a>.</td> | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This helps! |
||||||
</tr> | ||||||
</tbody> | ||||||
</table> | ||||||
|
||||||
<section id="enable_live_regions_with_aria-live"> | ||||||
<h4>Enable Live Regions with <code>aria-live</code></h4> | ||||||
|
||||||
<p> | ||||||
The <code>aria-live</code> attribute indicates that an element is a live region. | ||||||
Some roles implicitly set <code>aria-live</code>; this is discussed in a later section. | ||||||
</p> | ||||||
|
||||||
<ul> | ||||||
<li><code>assertive</code>: assistive technologies can interrupt the user to provide this information, | ||||||
but will not move the current focus, so the user's work flow is not interrupted.</li> | ||||||
|
||||||
<li><code>polite</code>: assistive technologies will provide this information after the user is done with their current task.</li> | ||||||
|
||||||
<li><code>off</code>: assistive technologies will not provide this information unless this region has focus.</li> | ||||||
</ul> | ||||||
|
||||||
<p> | ||||||
With the exception of a few roles, the default value of <code>aria-live</code> is <code>off</code>. | ||||||
</p> | ||||||
|
||||||
<p> | ||||||
For example, when the user types into a search field, the page could update the page with search results as the user is typing. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
redundant "the page" |
||||||
To inform users of assistive technology that this has happened, a polite live region can be used. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Remove potential confusion over "To inform users of something that happened..." |
||||||
When the user is done typing, and the search is complete, the user is informed of how many results were found, | ||||||
without having to move focus away from the search field. | ||||||
</p> | ||||||
|
||||||
<pre><code><form role="search" aria-labelledby="search"> | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Aside: What tool is being used to convert from markdown to markup? It seems to have a bug where it outputs |
||||||
<h2 id="search">Search</h2> | ||||||
<label>Search query: <input type="search" name="q" oninput="updateSearch(event)"></label> | ||||||
<div id="search-result-status" role="region" aria-live="polite"></div> | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Need to discuss with group whether a live region can use If so, then the ARIA spec needs to allow this use specifically for live regions. Or, if the live region in this example is truly intended to be a landmark, then in needs an accessible name (or else conformance tools are going to flag it as missing one). If, however, the group decides that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if it's not named then it shouldn't have a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Nope. :) Decision on the call was to delete I didn't want to state "No role" as the "best" choice without floating a bunch of other possibilities out there first - even the wacky possibility of changing the spec to allow live region elements to have a "non-landmark role=region". 😄 |
||||||
</form> | ||||||
<script> | ||||||
async function updateSearch(event) { | ||||||
const statusElement = document.getElementById('search-result-status'); | ||||||
const results = await getSearchResults(event.target.value); | ||||||
statusElement.textContent = `${results.length} result(s) found.`; | ||||||
showResults(results); | ||||||
} | ||||||
</script> | ||||||
</code></pre> | ||||||
</section> | ||||||
|
||||||
<section id="indicate_what_content_to_announce_with_aria-atomic"> | ||||||
<h4>Indicate What Content to Announce with <code>aria-atomic</code></h4> | ||||||
|
||||||
<p> | ||||||
The <code>aria-atomic</code> attribute takes the values "true" and "false". The attribute can also be omitted. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
To keep the first-time reader from thinking that discussion of the default value must be missing. |
||||||
</p> | ||||||
|
||||||
<p> | ||||||
When this attribute is set to <code>true</code>, assistive technologies will render the element as a whole, and not just parts that have been changed. | ||||||
</p> | ||||||
|
||||||
<p> | ||||||
When this attribute is set to <code>false</code>, assistive technologies will only render the changes (as per <code>aria-relevant</code>) to the user. | ||||||
</p> | ||||||
|
||||||
<p> | ||||||
When this attribute is omitted, the user agent will use the closest ancestor that has <code>aria-atomic</code> set to <code>true</code> or <code>false</code>, | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
or if there is no such ancestor, <code>false</code>. | ||||||
</p> | ||||||
|
||||||
<p> | ||||||
For example, consider a clock that can be set to notify the user of the current time at a regular interval. | ||||||
Without <code>aria-atomic</code>, the assistive technology might only notify the changed components, rather than the full time. | ||||||
</p> | ||||||
|
||||||
<pre><code><div id="clock" role="region" aria-live="polite" aria-atomic="true"> | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See previous discussion about |
||||||
The time is | ||||||
<span>16</span>:<span>34</span>:<span>05</span> | ||||||
</div> | ||||||
</code></pre> | ||||||
</section> | ||||||
|
||||||
<section id="indicate_which_content_changes_are_relevant_with_aria-relevant"> | ||||||
<h4>Indicate Which Content Changes are Relevant with <code>aria-relevant</code></h4> | ||||||
|
||||||
<p> | ||||||
The <code>aria-relevant</code> attribute can be used to inform assistive technologies about which kinds of changes are relevant to inform users about. | ||||||
It takes a list of keywords, with the following meanings: | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
</p> | ||||||
|
||||||
<ul> | ||||||
<li><code>additions</code>: Element nodes are added to the accessibility tree within the live region.</li> | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Consider adding "When" to these (short for "Relevant when..."). |
||||||
<li><code>text</code>: Text content or a text alternative is added to any descendant in the accessibility tree of the live region.</li> | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
<li><code>removals</code>: Text content, a text alternative, or an element node within the live region is removed from the accessibility tree.</li> | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
<li><code>all</code>: Synonym to <code>additions removals text</code></li> | ||||||
</ul> | ||||||
|
||||||
<p> | ||||||
If <code>aria-relevant</code> is not specified, then the value of the closest ancestor element with an <code>aria-relevant</code> attribute is used. | ||||||
Specifying the <code>aria-relevant</code> attribute on an element overrides any value specified on an ancestor element. | ||||||
If there is no ancestor element with an <code>aria-relevant</code> attribute, the default value <code>additions text</code> is used. | ||||||
</p> | ||||||
|
||||||
<p> | ||||||
For example, a disappearing old message in a chat log is not significant, and users do not need to be informed of the removal. | ||||||
However, for a list of online contacts, a disappearing contact is significant (it indicates that the contact is no longer online). | ||||||
Instead of announcing the removal of something, it is often better to add new content that tells the user what happened. | ||||||
For example, "Alice is now offline" is clearer than "Alice" or "Removed, Alice". | ||||||
Therefore, avoid using <code>removals</code> or <code>all</code>. | ||||||
</p> | ||||||
|
||||||
<p> | ||||||
For example, a list of online contacts: | ||||||
</p> | ||||||
|
||||||
<pre><code><div role="region" aria-live="polite" aria-labelledby="contacts"> | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See note above regarding |
||||||
<h1 id="contacts">Contacts</h1> | ||||||
<ul> | ||||||
<li aria-atomic="true"><a href="/contacts/alice">Alice</a> is now online</li> | ||||||
</ul> | ||||||
</div> | ||||||
</code></pre> | ||||||
|
||||||
<p> | ||||||
Note that this example omits the <code>aria-relevant</code> attribute, leaving it as the default value (<code>additions text</code>). | ||||||
</p> | ||||||
|
||||||
<p> | ||||||
When a contact comes online, it is added to the list, and users of assistive technology are informed of the addition without disrupting their current task. | ||||||
To communicate what happened, the text is "Alice is now online", rather than only "Alice". | ||||||
</p> | ||||||
|
||||||
<p> | ||||||
Similarly when a user goes offline, the text could be changed to "Alice is now offline", | ||||||
and then be hidden from the list after a timeout. | ||||||
</p> | ||||||
|
||||||
<p> | ||||||
If a contact changes their display name, the text change would also be announced: | ||||||
"Alice has changed their name to 4liz". | ||||||
After a timeout, the text "Alice has changed their name to " could be removed, without causing a new announcement. | ||||||
</p> | ||||||
</section> | ||||||
|
||||||
<section id="triggering_live_regions"> | ||||||
<h4>Triggering Live Regions</h4> | ||||||
|
||||||
<p> | ||||||
Additions and removals in the accessibility tree can happen due to changes to the DOM tree or changes to the applied CSS. | ||||||
For example, changing the CSS <code>display</code> property to <code>none</code> causes the element to be removed from the accessibility tree. | ||||||
See the <a href="#accessibility-tree">Accessibility tree</a> section for more details. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This section needs a bit more discussion. It seems to be missing a sentence that ties in Accessibility tree changes with triggering live regions. (It's implied by the section title, but I think it needs to be explicitly stated). Something like: Also, does setting |
||||||
</p> | ||||||
</section> | ||||||
</section> | ||||||
|
||||||
<section id="special_case_live_regions"> | ||||||
<h3>Special Case Live Regions</h3> | ||||||
|
||||||
<p> | ||||||
The roles listed below implicitly set the <code>aria-live</code> attribute to indicate that it is a live region. | ||||||
When using these roles, the <code>aria-live</code> attribute can be omitted, | ||||||
or it can be specified to change the value from the default. | ||||||
</p> | ||||||
|
||||||
<ul> | ||||||
<li><code>alert</code></li> | ||||||
<li><code>log</code></li> | ||||||
<li><code>status</code></li> | ||||||
<li><code>timer</code></li> | ||||||
<li><code>marquee</code></li> | ||||||
</ul> | ||||||
|
||||||
<section id="live_region_role_alert"> | ||||||
<h4>Live Region Role <code>alert</code></h4> | ||||||
|
||||||
<p> | ||||||
The <code>alert</code> role indicates important, usually time-sensitive, information. | ||||||
Use this role when focus is not moved to the message, and the user is not expected to close the message. | ||||||
For an alert dialog that can be closed, the the <code>alertdialog</code> role instead. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
</p> | ||||||
|
||||||
<p> | ||||||
The default value for <code>aria-live</code> is <code>assertive</code>. | ||||||
The default value for <code>aria-atomic</code> is <code>true</code>. | ||||||
</p> | ||||||
|
||||||
<p> | ||||||
See the <a href="#alert">Alert design pattern</a> and the related <a href="https://w3c.github.io/aria-practices/examples/alert/alert.html">Alert Example</a>. | ||||||
</p> | ||||||
</section> | ||||||
|
||||||
<section id="live_region_role_log"> | ||||||
<h4>Live Region Role <code>log</code></h4> | ||||||
|
||||||
<p> | ||||||
The <code>log</code> role indicates that new information is added in meaningful order and old information might disappear. | ||||||
</p> | ||||||
|
||||||
<p> | ||||||
The default value for <code>aria-live</code> is <code>polite</code>. | ||||||
</p> | ||||||
|
||||||
<p> | ||||||
For example, a chat log would be an appropriate use case for the <code>log</code> role. | ||||||
</p> | ||||||
|
||||||
<pre><code><h1 id="irc-log">IRC Log</h1> | ||||||
<div role="log" aria-labelledby="irc-log"> | ||||||
<p>[10:26] &lt;Charl> ok let's test it and see if it works</p> | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
This instance of |
||||||
<p>[10:59] &lt;hsivonen> morning</p> | ||||||
</div> | ||||||
</code></pre> | ||||||
</section> | ||||||
|
||||||
<section id="live_region_role_status"> | ||||||
<h4>Live Region Role <code>status</code></h4> | ||||||
|
||||||
<p> | ||||||
The <code>status</code> role indicates that content is advisory information for the user but is not important enough to justify an <code>alert</code>, often but not necessarily presented as a status bar. | ||||||
</p> | ||||||
|
||||||
<p> | ||||||
The default value for <code>aria-live</code> is <code>polite</code>. | ||||||
The default value for <code>aria-atomic</code> is <code>true</code>. | ||||||
</p> | ||||||
|
||||||
<p> | ||||||
Do not move focus to the element with script when the content is changed. | ||||||
</p> | ||||||
|
||||||
<p> | ||||||
For example, the search result summary example above could use <code>role="status"</code> instead of <code>role="region"</code>: | ||||||
</p> | ||||||
|
||||||
<pre><code><form role="search" aria-labelledby="search"> | ||||||
<h2 id="search">Search</h2> | ||||||
<label>Search query: <input type="search" name="q" oninput="updateSearch(event)"></label> | ||||||
<div id="search-result-status" role="status"></div> | ||||||
</form> | ||||||
</code></pre> | ||||||
|
||||||
<p> | ||||||
The HTML <code>output</code> element has the <code>status</code> role by default. | ||||||
The <code>output</code> element is defined to represent the result of a calculation performed by the application, or the result of a user action. | ||||||
The result of a user search is thus appropriate use of the <code>output</code> element: | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
</p> | ||||||
|
||||||
<pre><code><form role="search" aria-labelledby="search"> | ||||||
<h2 id="search">Search</h2> | ||||||
<label>Search query: <input type="search" name="q" oninput="updateSearch(event)"></label> | ||||||
<output id="search-result-status"></output> | ||||||
</form> | ||||||
</code></pre> | ||||||
</section> | ||||||
|
||||||
<section id="live_region_role_timer_and_marquee"> | ||||||
<h4>Live Region Role <code>timer</code> and <code>marquee</code></h4> | ||||||
|
||||||
<p> | ||||||
Usage of the <code>timer</code> and <code>marquee</code> roles is discouraged. | ||||||
</p> | ||||||
|
||||||
<p> | ||||||
The <code>timer</code> role is a numerical counter which indicates an amount of elapsed time from a start point, or the time remaining until an end point. | ||||||
The <code>timer</code> role is a subclass of the <code>status</code> role. | ||||||
The default value of <code>aria-live</code> value of <code>off</code>. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Redundant "value of". |
||||||
</p> | ||||||
|
||||||
<p> | ||||||
The <code>marquee</code> role indicates non-essential information that changes frequently. | ||||||
The default value of <code>aria-live</code> value of <code>off</code>. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove redundant "value of".
Suggested change
|
||||||
</p> | ||||||
|
||||||
<p class="note"> | ||||||
<a href="https://github.com/w3c/aria/issues/1104">Issue 1104 for the ARIA specification</a> proposes deprecating these roles. | ||||||
</p> | ||||||
</section> | ||||||
</section> | ||||||
</section> | ||||||
|
||||||
<section id="defer_exposing_content_updates_using_aria-busy"> | ||||||
<h2>Defer Exposing Content Updates using <code>aria-busy</code></h2> | ||||||
|
||||||
<p> | ||||||
Sometimes, it takes some time for a script to update the content of a live region or a widget. | ||||||
For example, it could be waiting on a network response. | ||||||
In order to avoid rendering half-baked content to users of assistive technology, | ||||||
the <code>aria-busy</code> attribute can be set to <code>true</code> while the content is being updated, | ||||||
and then to <code>false</code> when it is done. | ||||||
</p> | ||||||
|
||||||
<p> | ||||||
The ARIA specification allows, but does not require, assistive technologies to wait until <code>aria-busy</code> is changed to <code>false</code> before exposing content changes to the user. | ||||||
So assistive technologies are allowed to ignore the <code>aria-busy</code> attribute. | ||||||
</p> | ||||||
|
||||||
<p> | ||||||
For assistive technologies that honor the <code>aria-busy</code> attribute, one possible implementation strategy is to not announce any content for elements when <code>aria-busy</code> is set to <code>true</code>. | ||||||
Therefore, it is important that the attribute is changed back to <code>false</code> when the content ought to be available to the user. | ||||||
For example, when the update is complete, but also when there is an error, or if the update is aborted. | ||||||
Otherwise, content could be left inaccessible to assistive technology users. | ||||||
</p> | ||||||
|
||||||
<p> | ||||||
Consider the search form from the earlier example in the <a href="#live-regions">Live Resions</a> section. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
When the user starts typing a new search into the search field, the script would update the search results live region, | ||||||
and maybe update multiple times as new search results appear, | ||||||
but it would be a better experience for users of assistive technology to only be notified when the new search is complete. | ||||||
</p> | ||||||
|
||||||
<pre><code><form role="search" aria-labelledby="search"> | ||||||
<h2 id="search">Search</h2> | ||||||
<label>Search query: <input type="search" name="q" oninput="updateSearch(event)"></label> | ||||||
<div id="search-result-status" role="region" aria-live="polite"></div> | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See earlier discussion about |
||||||
</form> | ||||||
<script> | ||||||
async function updateSearch(event) { | ||||||
const statusElement = document.getElementById('search-result-status'); | ||||||
statusElement.ariaBusy = 'true'; | ||||||
statusElement.textContent = 'Searching...'; | ||||||
let results = null; | ||||||
try { | ||||||
results = await getSearchResults(event.target.value); | ||||||
statusElement.textContent = `${results.length} result(s) found.`; | ||||||
} catch (ex) { | ||||||
statusElement.textContent = "There was an error when searching. Please try again."; | ||||||
} | ||||||
statusElement.ariaBusy = 'false'; | ||||||
showResults(results); | ||||||
} | ||||||
</script> | ||||||
</code></pre> | ||||||
|
||||||
<p> | ||||||
The <a href="#feed">Feed Design Pattern</a> uses <code>aria-busy</code> in its example. | ||||||
A feed is a section of a page that automatically loads new sections of content as the user scrolls. | ||||||
While the feed is loading new content, <code>aria-busy</code> is set to <code>true</code> on the feed. | ||||||
</p> | ||||||
</section> | ||||||
|
||||||
<section id="names_and_descriptions"> | ||||||
<h2>Providing Accessible Names and Descriptions</h2> | ||||||
<p> | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.