Controlling what assistive technology sees
Fine-tuning a page for assistive technology users means making sure that only relevant parts of the DOM are exposed to accessibility APIs. There are several ways to do that.
Anything explicitly hidden from the DOM is also left out of the accessibility tree, so content with a CSS style of visibility: hidden, display: none, or the HTML5 hidden attribute will be hidden from assistive technology users as well. But an element that is not visually rendered yet not explicitly hidden is still present in the accessibility tree. One common approach is to include "screen reader only text" in an element that is position: absolute offscreen.
.sr-only {
position: absolute;
left: -10000px;
width: 1px;
height: 1px;
overflow: hidden;
}
You can also deliver screen reader only text by using an aria-label, aria-labelledby, or aria-describedby attribute that references an otherwise hidden element. See the WebAIM article on techniques for hiding text for more details.
ARIA itself offers a mechanism to exclude content that isn't visually hidden with the aria-hidden attribute. It removes the element and all of its descendants from the accessibility tree. The exceptions are elements referenced by aria-labelledby or aria-describedby.
<div class="deck">
<div class="slide" aria-hidden="true">
Sales Targets
</div>
<div class="slide">
Quarterly Sales
</div>
<div class="slide" aria-hidden="true">
Action Items
</div>
</div>
Consider a modal UI that blocks access to the main page. A sighted user sees a semi-transparent overlay, but a screen reader user may still be able to navigate to the rest of the page. To prevent that, you need to mark the out-of-scope parts of the page with aria-hidden in addition to creating the keyboard trap.
Marking live regions with aria-live
The aria-live attribute lets you designate a part of the page (a live region) whose updates should be announced to users immediately, regardless of where they are on the page. For example, a status message that appears after a user action is worth marking as live — if it is important enough to grab a sighted user's attention, it should also reach an assistive technology user.
Consider the difference between a plain div:
<div class="status">Your message has been sent.</div>
and the same element marked as live:
<div class="status" aria-live="polite">Your message has been sent.</div>
aria-live takes three values:
politetells assistive technology to announce the change when it finishes its current task. Use it for important but non-urgent updates; this covers mostaria-liveusage.assertiveinterrupts whatever assistive technology is doing and announces the change immediately. Reserve this for critical updates, such as "There has been a server error and your changes are not saved; please refresh the page" or input changes that come directly from user interactions like stepper buttons.offtemporarily suspendsaria-liveinterruptions.
A couple of things to watch out for. The aria-live region should generally be present in the initial page load; it is not a hard rule, but if the region isn't working, that is often the cause. Also, screen readers respond differently to changes — toggling a descendant's hidden style from true to false, for example, can trigger an alert on some readers.
Three additional attributes refine what gets announced when a live region changes. aria-atomic — set to true or false, with false the default — indicates whether the whole region should be read as a unit. With a date widget whose day, month, and year are in one live region, changing only the month with aria-atomic="true" causes the full widget content to be re-read.
aria-relevant specifies which types of changes matter, and can be used alone or as a token list:
- additions: elements added to the live region are significant. Appending a span to a log of status messages would announce that span when
aria-atomicisfalse. - text: text content added to any descendant is relevant. For instance, modifying a custom text field's
textContentproperty would read that text. - removals: the removal of text or descendant nodes gets communicated.
- all: every change is relevant.
The default is additions text, so if you don't specify aria-relevant, users will be informed of any addition to the element — usually what you want.
Finally, aria-busy tells assistive technology to ignore changes temporarily while content is loading. Once everything is in place, set it to false to restore normal reading.



