ARIA Live Region

아리아 라이브 리전

An attribute that makes a screen reader automatically announce content that changes on its own — a cart count, a save confirmation.

Also known as: Live regionaria-live
···
html
<div class="stage">
  <div class="pane app">
    <div class="tag">화면</div>
    <div class="cartRow">
      <div class="cartIcon"><span id="count">0</span></div>
      <button class="addBtn" id="addBtn"></button>
    </div>
  </div>
  <div class="pane sr">
    <div class="tag">SR transcript</div>
    <div class="log" id="log"></div>
  </div>
</div>
css
.stage{width:94%;height:88%;display:flex;gap:4%}
.pane{position:relative;flex:1;border-radius:14px;border:1px solid var(--line);background:var(--surface);overflow:hidden}
.tag{position:absolute;top:8px;left:10px;font:700 10.5px/1 ui-monospace,monospace;color:var(--muted)}
.app{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10%}
.cartRow{width:64%;display:flex;align-items:center;justify-content:center;gap:14%}
.cartIcon{position:relative;width:36px;height:36px;flex:none;border-radius:9px;border:2px solid var(--fg);display:grid;place-items:center;font:800 13px/1 ui-monospace,monospace;color:var(--fg)}
.addBtn{width:40px;height:32px;flex:none;border-radius:9px;background:var(--accent);border:none;transition:transform .15s ease}
.log{position:absolute;inset:26px 10px 10px;display:flex;flex-direction:column-reverse;gap:6px;font:10.5px/1.3 ui-monospace,monospace;color:var(--accent-3);overflow:hidden}
.log div{opacity:0;transform:translateY(4px);transition:opacity .3s ease,transform .3s ease}
.log div.show{opacity:1;transform:translateY(0)}
js
const btn = document.getElementById('addBtn');
const countEl = document.getElementById('count');
const log = document.getElementById('log');
let n = 0;
function addLine(text) {
  const line = document.createElement('div');
  line.textContent = text;
  log.prepend(line);
  requestAnimationFrame(function () { line.classList.add('show'); });
  while (log.children.length > 4) log.removeChild(log.lastChild);
}
function tick() {
  n++;
  countEl.textContent = String(n);
  btn.style.transform = 'scale(0.9)';
  setTimeout(function () { btn.style.transform = 'scale(1)'; }, 150);
  addLine(n + (n === 1 ? ' item in cart' : ' items in cart'));
}
tick();
setInterval(tick, 2000);

When content changes somewhere the user isn't focused — a cart count, a "saved" toast, a results count — sighted users notice it visually, but screen reader users get no signal at all unless the region announces itself. An element with `aria-live="polite"` waits for the screen reader to finish its current sentence, then reports the change; `aria-live="assertive"` interrupts immediately.

`polite` is the default and almost always the right choice. `assertive` is for genuinely urgent warnings, like a session about to expire — overusing it keeps cutting the user off mid-sentence. For a message that appears as a whole new element, like a form error, `role="alert"` (implicitly assertive) is common too.

Left is the actual screen; right is a transcript of what a screen reader actually speaks. Every time the button auto-adds an item, a new line appears on the right independent of what's visually happening on the left.

When to use

Use it anywhere content updates without a focus change: toast notifications, live counters, autocomplete result counts, form validation summaries. Don't wire it to every tick of an animated number or spinner — it'll chatter constantly.