Accessible forms with ARIA live regions

When a form is used to update information on the page, it can be troublesome for screen reader users. Unless the screen reader is focused on the relevant bit of the page, the update goes by un-noticed. ARIA live regions are a simple way to improve the experience for screen reader users.

Quick recap: Screen readers rely almost entirely on the HTML of the page, and focus is moved from one element to another using a range of navigation commands. In other words, a screen reader can only focus on one element at a time.

That’s where the trouble starts. If a screen reader is focused on a form field, it can’t be focused on the bit of the page being updated as well.

Dynamic updates

The Marks & Spencer website is a good example. When an item is added to the shopping basket, the basket summary at the top right of the page gets updated. In fact it’s the only confirmation that the item has been successfully added.

The update is easy to see at a glance, but not at all easy with a screen reader. First you have to discover that something has changed, then you have to find out where it happened. Even once you know this, you still need to move focus back and forth between the summary and the product information, every time you add an item to the basket.

Code example: without ARIA

A massively simplified version of this interaction might look like this:

< !DOCTYPE html>
<html lang="en">


    var items = 0;
	function updateItems () {
		items = items + 1;

<p>Tequila makes me happy...</p>
<p><button onclick="updateItems()">Add tequila to basket</button></p>

<h2>Basket summary</h2>
    <p>Your basket contains <span id="quantity">0</span> items.</p>


When the button is activated with a screen reader, nothing appears to happen. The page doesn’t reload, so focus remains on the button and the screen reader stays silent. The basket summary is updated, but the screen reader user remains oblivious.

The aria-live attribute

The aria-live attribute can be used to turn the basket summary into an ARIA live region. ARIA enabled screen readers can monitor ARIA live regions for changes, and automatically announce them as they happen. The monitoring is done in the background, so even if the screen reader is focused somewhere else on the page at the time, changes within the live region are still announced.

Code example/: with aria-live

Adding the aria-live attribute to the basket summary:

<h2>Basket summary</h2>
<div aria-live="assertive">
    <p>Your basket contains <span id="quantity">0</span> items.</p>

The aria-live attribute takes three possible values: off (default), polite and assertive. The polite value means that the screen reader will wait until its finished it’s current task before announcing the update, and the assertive value means the update is announced as soon as the screen reader encounters a slight pause (in reality it’s almost always immediate).

The aria-atomic attribute

The aria-atomic attribute defines whether all of the content in the ARIA live region should be announced, or only the part that’s changed.

Code example: with aria-atomic

Adding the aria-atomic attribute to the basket summary:

<h2>Basket summary</h2>
<div aria-live="assertive" aria-atomic="true">
    <p>Your basket contains <span id="quantity">0</span> items.</p>

The aria-atomic attribute has two possible values: true and false (default). Using aria-atomic=”true” means that all of the content within the ARIA live region will be announced, even though only a small part of it has changed. So screen readers will announce something like “Your basket contains 3 items”, instead of just “3”. Try the accessible forms demo to see it in action.

The All Star route deviation calculator is one of the best examples of this technique in the wild. Developed by Matt Lawson of Nomensa, the form is used to calculate cost savings based on reduced mileage.

As you manipulate information within the form, your potential cost saving is dynamically updated on the page. Because the updated information is an ARIA live region, using the form with a screen reader couldn’t be easier.

5 comments on “Accessible forms with ARIA live regions”

Skip to Post a comment
  1. Comment by Stomme poes

    Would be interesting to see examples of multiple updates per single action (add an item to the cart; see updated subtotal, total, shipping change). What would determine the order? What if it’s in a table where the name of the item being updated is in another cell? I’m not positive after the tests done recently by Detlev Fischer on tables.

  2. Comment by Léonie Watson

    If you extend the example in the post so that two bits of information are updated inside the live region, it seems to work ok. The same is true if you pull them apart and put them in separate live regions.

    The updates are announced based on their place in the source order.

    Things seem to get a bit messy when the live region is applied to a table though because the relationship between the column/row headers and the cell content isn’t expressed properly by the screen reader. That’s the problem with using tables to control layout of course.

  3. Comment by Stomme poes

    It’s also a problem for using tables for anything else, like a table of products, a calendar of events, or a shopping cart.

    I’ve considered turning our shopping carts into lists after Fischer’s tests, but decided not to. It’s always hard deciding between semantic markup and working around bugs of browsers and AT.

    I will want to play around with adding in live regions though. Gotta sneak it past the bosses first of course.

  4. Comment by Gerry Neustatl

    Is there a way to dictate a precise order that aria-live announcements are made?
    For example if 3 aria-live regions each update, and announcing them out of source code sequence would be more logical
    e.g. give each live region a unique ID and take focus to a div with aria-labelledby=”ID2 ID1 ID3″, or similar

    1. Comment by Léonie Watson

      @Gerry, no this can’t be controlled. The live region announcement is triggered as soon as the content inside the live region changes.

      Be careful with multiple live regions on the same page, especially if they update close together in time. If one announcement hasn’t finished when the next is triggered, it will be interupted (mid-sentence) by the new update.

      It may be possible to impose some form of control by using the JavaScript that manages the updates, to put in place delays between the updates to the respective live regions and/or between updates in the same live region though. Again, this isn’t a robust approach, because things like network latency can affect the delivery of JS driven functionality, which will in turn affect the timing of the live region updates.

Comment on this post

Will not be published

This site uses Akismet to reduce spam. Learn how your comment data is processed.