References

Beginner-friendly references for web development, with live, editable examples.

The HTML aria-relevant attribute

ARIA Accessibility
In short

Inside a live region, aria-relevant lists which kinds of change count, from additions, removals, text and all. The default, additions text, leaves removals out. The list is a suggestion, and assistive technology isn't required to present every listed type.

Overview

The aria-relevant attribute indicates what notifications a browser triggers when the accessibility tree inside a live region changes. It's a global attribute, and its job is to separate meaningful changes from presentational ones once a live role or aria-live has made the region live.

Two lists show the difference. Lines dropping off the top of a log only make room for new entries, so their removal means nothing. A name leaving a buddy list means that person went offline, so a buddy list is a case for all.

Each token covers one kind of change. With additions, element nodes added to the tree count. With text, text or a text alternative added to a descendant counts. With removals, any text, text alternative or element node leaving the tree counts. Write several separated by spaces, or all for the three.

A text change reaches beyond the characters in the region. When text changes are relevant, browsers must watch any descendant change that affects the name computation, so a new alt on an image counts. A change to a label outside the region doesn't count, even if an element inside references it.

Chrome's accessibility tree reports the value as written on a live region and leaves it out elsewhere, even with aria-live="off", while Firefox reports it in both cases.

Syntax

<ul aria-live="polite" aria-relevant="additions removals">
  <li>Sam</li>
</ul>

Values

Value
A space-separated list of additions, removals and text, or the single value all.

Example

Live example
<p style="margin:0 0 8px">Pick a value, then press a button to see how the spec classes that change.</p>
<label for="mode">aria-relevant</label>
<select id="mode">
  <option>additions text</option>
  <option>additions</option>
  <option>additions removals</option>
  <option>all</option>
</select>
<ul id="team" aria-live="polite" aria-relevant="additions text" style="margin:8px 0">
  <li id="sam">Sam, online</li>
  <li>Priya, online</li>
</ul>
<button id="member" type="button">Dana joins</button>
<button id="status" type="button">Sam goes away</button>
<p id="state" role="status" style="margin:8px 0 0"></p>
<script>
const team = document.getElementById('team');
const mode = document.getElementById('mode');
const member = document.getElementById('member');
const statusButton = document.getElementById('status');
const sam = document.getElementById('sam');
const state = document.getElementById('state');

function counts(type) {
  const tokens = team.getAttribute('aria-relevant').split(' ');
  return tokens.includes(type) || tokens.includes('all') ? 'relevant' : 'not relevant';
}
mode.addEventListener('change', () => {
  team.setAttribute('aria-relevant', mode.value);
  state.textContent = 'aria-relevant is now ' + mode.value + '.';
});
member.addEventListener('click', () => {
  const dana = document.getElementById('dana');
  if (dana) {
    dana.remove();
    member.textContent = 'Dana joins';
    state.textContent = 'Removed row: ' + counts('removals') + '.';
  } else {
    const row = document.createElement('li');
    row.id = 'dana';
    row.textContent = 'Dana, online';
    team.append(row);
    member.textContent = 'Dana leaves';
    state.textContent = 'Added row: ' + counts('additions') + '.';
  }
});
statusButton.addEventListener('click', () => {
  const away = sam.textContent.endsWith('online');
  sam.textContent = away ? 'Sam, away' : 'Sam, online';
  statusButton.textContent = away ? 'Sam comes back' : 'Sam goes away';
  state.textContent = 'New text: ' + counts('text') + '. Old text: ' + counts('removals') + '.';
});
</script>

Best practices

  • Use the removals and all values of aria-relevant sparingly. A removal is worth reporting only when it means something, such as a person leaving a team list.
  • Set aria-relevant once on the region unless a child needs a different list. A value on a descendant replaces the inherited list, so text on a child drops additions there.
  • Check how it combines with aria-atomic. What aria-atomic presents depends on the change notifications aria-relevant sets, so with aria-atomic set to true, one relevant change can bring in the whole region.
  • Reserve a live region for content that has relevant changes. If none seems the right value, the element shouldn't be a live region.

Frequently asked questions

Which changes does aria-relevant cover by default?
By default, aria-relevant covers additions and text, written as additions text. Removed nodes are treated as irrelevant unless you add removals or all.
Why is the old text ignored when aria-relevant is left at its default?
Replaced text counts as an addition and a removal, and the default aria-relevant value excludes removals. When Online changes to Away, the new word counts and the old one doesn't.
Is aria-relevant inherited?
Yes, an element without aria-relevant takes the value of its nearest ancestor that sets one. Values on different levels don't add together.
Is none a valid value for aria-relevant?
No, none isn't a supported aria-relevant value, even though Chrome's and Firefox's accessibility trees pass it through as written.
Does aria-relevant do anything outside a live region?
No, aria-relevant applies only inside a live region, since it's defined for changes within one.
Does JavaScript have a property for aria-relevant?
Yes, ariaRelevant is the string form of aria-relevant, supported since Chrome 81, Firefox 119 and Safari 12.1. WAI-ARIA 1.2 left it out of its IDL, and only the 1.3 Working Draft has it, so no Recommendation defines it.