Skip to content

JavaScript Tutorial Accessibility with JavaScript

Announcing Dynamic Content with Live Regions

Lesson 220 of 258 2 min read By Deepak Paswan Updated Oct 4, 2026

When JavaScript changes content on the page (a message appears, a counter updates, search results load), sighted users see it. A screen reader user hears nothing, unless you tell assistive technology to announce it. Live regions do that.

The basic idea

An element marked as a live region is watched. When its text changes, the screen reader reads the new text.

index.html
HTML
<button id="add">Add to cart</button>
<p id="cart-status" aria-live="polite"></p>
<script>
  let count = 0;
  document.querySelector("#add").addEventListener("click", () => {
    count++;
    document.querySelector("#cart-status").textContent = `${count} item${count === 1 ? "" : "s"} in your cart`;
  });
</script>

The paragraph is silent until its content changes, then a screen reader says, for example, “2 items in your cart”.

aria-live values

ValueBehaviour
politewaits until the user is idle, then announces. Use this almost always.
assertiveinterrupts immediately. Only for urgent messages.
offnot announced (the default)

Handy roles with built-in live behaviour

RoleMeaningEquivalent to
role="status"a status message (saved, loading, results count)aria-live="polite"
role="alert"an important error or warningaria-live="assertive"
index.html
HTML
<p role="status" id="saved"></p>
<div role="alert" id="error"></div>

Rules that make it work

  1. The live region must already exist in the page when it loads, ideally empty. A region added together with its message is often not announced.
  2. Change the text inside it. Hiding and showing it with CSS is less reliable.
  3. Keep messages short and clear.
script.js
JS
const status = document.querySelector("#status");

function announce(message) {
  status.textContent = "";                    // clear first, so repeats are announced again
  setTimeout(() => { status.textContent = message; }, 50);
}

Good uses

  • “Item added to cart”, “Saved”, “3 results found”.
  • Form errors and success messages (Accessible Validation).
  • Loading states: “Loading…” then “Loaded” (Loading States).
  • Live scores, chat messages, progress.

Mistakes

  • Announcing too much. A region that changes every second becomes noise. Announce results, not progress ticks.
  • Using assertive for normal updates. It is rude, and it interrupts what the user is reading.
  • **Moving focus and announcing** the same thing, which can double the speech.
  • Putting a big container in a live region: every small change inside is read again.
  • Making visual-only changes (colour, icons) with no text.

Alternatives

Moving focus to new content (a heading, an error summary) is often better than a live region when the user needs to act on it. Use a live region for information the user does not need to act on right away.

Visually hidden messages

If the message is only for screen reader users, keep it in the page but hide it visually:

style.css
CSS
.visually-hidden {
  position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
lightbulb
Test
Turn on a screen reader (or use the browser’s accessibility tools) and trigger your update. If you cannot tell it happened without looking, neither can a blind user.