Using aria-live

Many web pages today have their content dynamically changed using Javascript. An example of this is the search page on this blog. When the page is initially loaded, the only content in the <main> section of the page is a search form. But, when you type in a query such as “css” and search, several articles related to that term begin to appear on the page.

If you are looking at the page, it is obvious when the articles appear because you can see the content change. However, if you’re using a screen reader, there is no way to tell exactly when this happens. The aria-live attribute allows us to tell assistive technology what parts of the page are likely to change. With this information, it can listen for changes to those particular elements and notify the user of any updates made.

How aria-live works

The aria-live attribute is added to specific HTML elements which we expect the content within them to change and we want the change to be communicated to users of assistive technology.

<div aria-live="polite">
    <!-- content will be updated with Javascript -->
</div>

The attribute has three potential values which control if and how changes are communicated.

aria-live="off"

The off value is practically the same as if the attribute was omitted entirely. Assistive technology will not keep track of changes to the elements content and, as such, will not notify its users of any changes.

In the example below, I have a <button> element which, on click, will update the content of the <div> below it.

<button onclick="document.getElementById('content').textContent = 'I have changed!'">
    Click me to change the content of the div element below
</button>

<div id="content" aria-live="off">
  My content will change
</div>

As you’ll see in the video below, since the <div> has the aria-live value of off, nothing happens when the button is clicked and the content changes.

aria-live="polite"

The polite value, will ensure that users of assistive technology will be notified of any changes to the element. The notification will happen at the next available point, meaning that there will not be an interruption to whatever task or information the user was currently in the process of.

Using the same example above but with the polite value, you’ll see that the screen reader waits to finish reading the label of the button before speaking the contents of the changed <div>.

aria-live="assertive"

Finally, the assertive value will communicate changes to the element immediately, disrupting any other task or information the user was currently in the process of.

Again, using the same example above but with the assertive value, you’ll see that the screen reader interrupts reading the label of the button to speak the contents of the changed <div>.

Considerations when using aria-live

If applied incorrectly, the aria-live attribute can do more harm than good. So, it’s important to take into account a few things if we want to use it.

Include aria-live in the initial markup

Assistive technology will initially scan the document for instances of the aria-live attribute and keep track of elements that include it. This means that, if we want to notify users of a change within an element, we need to include the attribute in the original markup. In other words, we should not use Javascript to add the aria-live attribute to elements dynamically.

<div class="will-change">
    <!-- content will be updated with Javascript -->
</div>

<script>
document.querySelector(".will-change").setAttribute("aria-live", "polite");

document.querySelector(".will-change").textContent = "New content!";
<script>
Don’t do this!

Instead, make sure that any elements that will change and needs their changes communicated, already have the aria-live attribute:

<div aria-live="polite" class="will-change">
    <!-- content will be updated with Javascript -->
</div>

<script>
document.querySelector(".will-change").textContent = "New content!";
<script>
Do this instead

Only apply aria-live to specific elements, not the entire page

You may be thinking that a good workaround to using aria-livewould be to just include the attribute on the <body> element so assistive technology will keep track of any and all changes on the page.

<body aria-live="polite">
    <header></header>
    <main>
        <p class="will-change"><!-- content will change --></p>
        <div class="will-change"><!-- content will change --></div>
    </main>
    <footer></footer>
</div>
Don’t do this!

The problem with this is every single change made on the page will be communicated to the user. Think of a single page application, for example. If the main content of the page changes, the assistive technology will try to read out every single piece of text that has changed on the page, which will essentially be the entire content of the page.

This is rarely what we actually want to happen. So, we should only use aria-live on the elements which we want their change in content actively communicated to the user.

<body>
    <header></header>
    <main>
        <p aria-live="polite" class="will-change"><!-- content will change --></p>
        <div aria-live="polite" class="will-change"><!-- content will change --></div>
    </main>
    <footer></footer>
</div>
Do this instead

Be polite

As we saw in my demo above, the assertive value will interrupt whatever task the screen reader user is in the middle of to announce any changes to the page. Therefore, it is important to only use this value if it is absolutely necessary to communicate changes immediately as they come. In most cases, the polite value is sufficient.

Switch off

If we are certain that an element will no longer be updated, use the off value to tell assistive technology that it no longer needs to keep track of changes.

// Change content
document.querySelector(".will-change").textContent = "New content!";

// Stop tracking changes to the element
document.querySelector(".will-change").setAttribute("aria-live", "off");

Applying aria-live: an example

As I mentioned at the start of this article, a good use case for the aria-live attribute is for places where content on the page is dynamically updated, such as the search page on this blog.

I recently updated that page to include this attribute. All I did was add the aria-live attribute to a <span> element, the content of which is updated when a user interacts with the form.

<section id="search-results" role="region">
    <span id="search-results-message" aria-live="polite">
        Use the <a href="#search-form">search form</a> above to search for articles.
    </span>
</section>

When the form is submitted, the contents of the #search-results-message element changes to display the number of articles found. This way, the user is informed of the completion of the search and they can continue to navigate the page as expected.

Here is how a screen reader user would interact with the form, before and after the implementation.

blog comments powered by Disqus