Every web developer working with the web accessibility (
WAI ARIA) knows or heard about
aria-live. This is an attribute, which indicates a live region - any updatable HTML element - and describes the types of updates the user agents, assistive technologies (screen readers), and user can expect from the live region. The default value of the
aria-live is
off. That means, updates to the region will not be presented to the user unless the assistive technology is currently focused on that region. The value
polite means, assistive technologies should announce updates at the next graceful opportunity, such as at the end of speaking the current sentence or when the user pauses typing. There is also the value
assertive, which forces assistive technologies to notify the user immediately. In additional, the
aria-relevant attribute can specify if the updates on the live region should only be spoken when the corresponding DOM node is added or removed or both.
Most time you need to set the value once and don't care about it. E.g. markup for error messages can contain
aria-live="polite".
<div class="messages" aria-live="polite">
... some messages ...
</div>
Every time when the content of the
div container with
class="messages" is updated, it will be spoken by screen readers. That's good, but sometimes you only would like to notify a sightless user when the new (after update) and old (before update) contents are not equal. Imagine a railway ticket shop where users can choose fare class, number of traveler, book places, etc. The total buy price is permanently updated. We can write
<span aria-live="polite">
<div id="pricetotal">
<span class="hiddenOfScreen">Total price </span>
#{price}
</div>
</span>
and update the
div by AJAX.
#{price} is a current price as EL expression calculated on the server-side (coming from the JSF world, but JavaScript templating has similar expressions). Whenever the
div gets updated, screen readers speak the total price regardless if the amount was changed or not. A more clever approach sets
aria-live dynamically at runtime. If the amount was changed, the
aria-live on the
div should have the value
polite. If the old and new prices are equal, the
div should have the value
off. The
off value prevents speaking by screen readers.
The idea is to save the last updated price in the
data-price attribute of the parent element and compare the old and new prices on every AJAX update. In the code snippet below, the
div with
id="pricetotal" gets updated. The JavaScript block inside is being executed on every update. We read and compare old and new prices and manipulate the
aria-live attribute at runtime. Whenever the
aria-live is set to
polite, screen readers speak "Total price" and the amount.
<span data-price="#{price}">
<div id="pricetotal">
<span class="hiddenOfScreen">Total price </span>
<span class="priceoutput">#{price}</span>
<script type="text/javascript">
$(document).ready(function () {
$pricetotal = $('#pricetotal');
var oldPrice = $pricetotal.parent().data('price');
var newPrice = $pricetotal.find('.priceoutput').text();
if (oldPrice != newPrice) {
$pricetotal.attr('aria-live', 'polite');
$pricetotal.parent().data('price', newPrice);
} else {
$pricetotal.attr('aria-live', 'off');
}
});
</script>
</div>
</span>
If prices are not equal, the new price is saved in the
data-price to make it available in the next update.