ARIA live regions

Overview – ARIA live regions

Introduced to make dynamic page content accessible to screen readers users, ARIA live regions are regions of a web page that announce dynamic updates to their content when the user’s attention and system focus are elsewhere. Example use cases of live regions include:

  • User receives a Facebook/Twitter notification
  • Stock ticker price increases
  • New chat message is received
  • Progress bar updates
  • Form validation error occurs
  • Shopping cart total updates
  • A sport scoring section updates periodically to reflect game statistics
  • A visible countdown announces once a minute
  • User presses the “next" carousel button to advance a slide (slide content is announced)
  • User sorts a table by name, prompting the announcement “Sorted alphabetically by name". In this case, the live text may be visually hidden as sighted users don’t need the notification.

WAI-ARIA provides four attributes that enable the author to identify live regions and their properties: aria-live, aria-relevant, aria-atomic, and aria-busy. WAI-ARIA also provides five specialized roles for specific types of live regions.

aria-live

Identify a live region with an aria-live attribute on a container element, such as a <span> or <div>. Browsers and the accessibility API monitor the container for any script-injected text. As soon as text is injected into the live region, a screen reader will announce it.

The live region must be empty on page load or when it’s first added to the DOM. It’s preferable to add the live region on page load, but if adding the live region to the DOM dynamically, it’s best practice to wait at least 2 seconds for the accessibility API to identify it before injecting any text.

The aria-live attribute takes three possible values: assertive, polite or off.

aria-live="assertive"
An assertive announcement interrupts whatever a screen reader is reading. Only use assertive announcements when the user needs immediate feedback.
aria-live="polite" 
A polite announcement is delayed until the screen reader finishes its current sentence or until the user pauses typing. Use the polite value most of the time.
aria-live="off"
Tells screen readers to temporarily suspend aria-live interruptions.

The WAI-ARIA Carousel Carousel (Slide Show or Image Rotator) described in module 12 uses aria-live="off" on the slide container when advancing slides automatically, and aria-live="polite" when the user is manually advancing the slides. This prevents an automatic slideshow’s announcements from overwhelming a screen reader user trying to read the page, and facilitates the reading of a manually-operated slideshow.

  Good example: aria-live attribute

Here, a <div> element provides a container for a live region, identified by the aria-live="polite" attribute. The element is empty on page load.

HTML

<div aria-live="polite" class="wb-inv"></div>

After the user clicks a sort button in a table column header, JavaScript populates the <div> with text. The screen reader announces “Sorted alphabetically by name".

HTML

<div aria-live="polite" class="wb-inv">
   Sorted alphabetically by name
</div>

Because the result of the sort is apparent to visual users, the live region is visually hidden with the WET CSS class .wb-inv.

CSS

.wb-inv {
   clip: rect(1px,1px,1px,1px);
   height: 1px;
   margin: 0;
   overflow: hidden;
   position: absolute;
   width: 1px;
}

aria-atomic

Use the aria-atomic attribute to specify if the whole live region should be announced, or only the text that changed.

aria-atomic="false"
When a live region is updated, only the updated text is announced. Use this value when the updated text makes sense on its own. This is the default value.
aria-atomic="true"
When a live region is updated, the entire region is announced. Use this value when the neighbouring static text in the live region provides necessary context to make sense of the updated text.

  Good example: aria-atomic false vs true

In these examples, the updated total price in a purchase process is announced when the user adds a product.

In this first example, the aria-atomic attribute is not used, so the default value applies, which is "false". Only the dynamic content is announced, that is, the price. If the dynamic content isn’t meaningful on its own, it can easily confuse users. In this case, the dynamic content alone is vague: "$84.52".

HTML

<p aria-live="polite">
   Total price:
   <span id="total-price">$84.52</span>
</p>

In this second example, the aria-atomic attribute is set to "true". All the content of the live region is announced, providing the necessary context to make sense of the dynamic content: "Total price: $84.52".

HTML

<p aria-live="polite" aria-atomic="true">
   Total price:
   <span id="total-price">$84.52</span>
</p>

aria-relevant

The aria-relevant attribute specifies which types of changes to a live region should be announced.

aria-relevant="all"
All changes are announced. Use with caution, as this setting can be verbose.
aria-relevant="additions"
Insertion of nodes to the live region are announced.
aria-relevant="removals"
Removal of nodes to the live region are announced. Reserve for important changes, such as a colleague leaving a chat room.
aria-relevant="text"
Changes to the text content (including text equivalents, such as alt text) in the live region are announced.

A live region has an implicit aria-relevant value of “additions" and “text", so the attribute isn’t needed if the design calls for the normal behaviour of announcing added content. Only use the aria-relevant attribute if you need to communicate the removal of content from a live region.

aria-busy

Use the aria-busy attribute to notify assistive technology that it should temporarily ignore changes to an element when things are loading. Set aria-busy="true" initially and, once everything is in place, clear the attribute or set it to aria-busy="false".

Special types of live regions

role="alert"

Use the ARIA alert role to announce important and typically time-sensitive information that requires the user’s immediate attention. Setting role="alert" is equivalent to setting aria-live="assertive" and aria-atomic="true". The only difference is that some screen readers begin the announcement by saying "alert", to identify it to users as an alert.

 Good example: Using role="alert"

In this example, a <div> element has a role="alert" attribute and is set via CSS to display: none.

Removing the CSS display: none value triggers the live announcement. Exposing such previously-hidden text is equivalent to injecting text.

The initial alert has the class name hidden, which hides the alert text with CSS display: none.

HTML

<form id="updateProfile" method="post" action="javascript:void(0)">
   <p><button>Update profile<button></p>
   <div class="confirm hidden" role="alert">You profile has been updated.</div>
</form>

CSS

.hidden { display: none; }

The alert is triggered by removing the CSS class name hidden

HTML

<form id="updateProfile" method="post" action="javascript:void(0)">
   <p><button>Update profile<button></p>
   <div class="confirm" role="alert">You profile has been updated.</div>
</form>

role="status"

Use the ARIA status role to announce advisory information to the user that is less urgent than an alert. Setting role="status" is equivalent to setting aria-live="polite" and aria-atomic="true".

If an element on the page controls what appears in the status, assign the controlling element the aria-controls="IDREF" attribute, pointing to the id attribute value of the element with role="status".

  Good example: Use role="status"

In this example, a paragraph with the role="status" attribute displays the number of items in a shopping cart. Because role="status" by default uses aria-atomic="true", the whole contents of the paragraph are announced. When the count updates, the live announcement kicks in. Screen readers declare the visually-hidden text "Shopping cart", the revised count, and the word "items".

The title attribute on the <span> holding the icon provides a visual label for mouse users. Since support for the title attribute is inconsistent across screen readers, the element is hidden from all of them (using the aria-hidden="true" attribute) and the more reliable visually-hidden text is used to label the icon (using the WET CSS class .wb-inv).

The aria-controls="IDREF" attribute is set on the button and given the id attribute value of the element holding the role="status" attribute.

Shopping cart 0 items

HTML

<p role="status" id="cart">
   <span title="Shopping cart" aria-hidden="true" class="glyphicon glyphicon-shopping-cart"></span>
   <span class="wb-inv">Shopping cart</span>
   <span id="cart-count">0</span> 
   items
</p>
<button id="btn" onclick="buy()" aria-controls="cart">Add to cart</button>
View JavaScript
let counter = 0;
function buy() {
   counter += 1;
   document.getElementById("cart-count").innerHTML = counter;
}
View CSS
.wb-inv {
   clip: rect(1px,1px,1px,1px);
   height: 1px;
   margin: 0;
   overflow: hidden;
   position: absolute;
   width: 1px;
}
.glyphicon {
   position: relative;
   top: 2px;
   display: inline-block;
   font-family: "Glyphicons Halflings";
   font-style: normal;
   font-weight: 400;
   line-height: 1;
   -webkit-font-smoothing: antialiased;
}
.glyphicon-shopping-cart:before {
    content: "\e116";
}

role="timer"

Use the ARIA timer role to identify a numerical counter listing the time elapsed from a starting point or the time remaining until an end point. The role has the implied value of aria-live="off", to prevent frequent announcements from overwhelming the screen reader user. However, you can announce the time at regular intervals by using JavaScript to briefly set the aria-live="assertive" and role="alert" attributes, overruling aria-live="off" and role="timer".

  Good example: Countdown announcing at intervals

In this example, a countdown uses the role="timer", so is silent in screen readers due to its implicit aria-live="off" setting.

HTML

<div id="countdown" role="timer" aria-atomic="true">
   <span id="number">60</span> seconds left!
</div>

However, at 15-second intervals, JavaScript briefly adds the aria-live ="assertive" attribute and replaces the timer role with role="alert". Screen readers announce the initial alert, “60 seconds left!", then the time remaining every 15 seconds: “45 seconds left!", etc.

HTML

<div id="countdown" role="alert" aria-live="assertive" aria-atomic="true">
   <span id="number">45</span> seconds left!
</div>

An interval of 15 seconds between announcements is too brief in practice and is done here simply to illustrate the technique. One minute is a more practical interval.

Try visiting the live demo (Opens in new tab) with a screen reader running.

View JavaScript
function decrement() { 
   var numElement = document.getElementById('number'); 
   var newNumber = parseInt(numElement.textContent - 1); 
   if (newNumber > -1) { 
      numElement.textContent = newNumber; 
   } 
   if ((newNumber % 15)===0 || newNumber == 0) {
      setAlert();
   } 
} 

function setAlert() {
   var liveRegion = document.getElementById('countdown'); 
   liveRegion.setAttribute('aria-live', 'assertive'); 
   liveRegion.setAttribute('role', 'alert'); 
   setTimeout(function() { 
      liveRegion.removeAttribute('aria-live'); 
      liveRegion.setAttribute('role', 'timer'); 
   }, 999);
}

window.setInterval(function() { 
   decrement(); 
}, 1000); 

window.addEventListener('load', function () {
   setAlert(); //alert on 60 seconds (or beginning)
});

role="marquee"

Use the ARIA marquee role to define an area as a type of live region with non-essential announcements that change frequently. Examples include stock tickers and frequently-changing ad banners.

Elements with the marquee role have an implicit aria-live="off". As with the timer role, the content changes too frequently to announce in screen readers. Screen reader users can still navigate to the area to read the text.

A marquee is required to have an accessible name. If a visible label is present use the aria-labelledby attribute; otherwise, use aria-label.

role="log"

Use the ARIA log role to keep track of sequential updates, such as a chat log, messaging history, game log or an error log. New information is added to the end, old information is optionally removed from the beginning. Updates to the live region are announced when the user is idle. The live region defined by role="log" has implicit aria-live="polite" and aria-atomic="true" attribute values.

Related WCAG resources

Related WCAG resources

Success criteria

Techniques

WAI-ARIA 1.1

Back to top