Loading Developer Playground

Loading ...

Skip to main content
ARIA ATTRIBUTELive Region Attributes

aria-live

Indicates that an element will be updated, and describes the types of updates the user can expect from the live region. The core attribute for creating live regions.

Attribute Type
Live Region
Value Type
off | polite | assertive
Default Value
off

Overview

The aria-live attribute is the foundation of ARIA live regions. It tells screen readers that content within an element will change dynamically and should be announced to users.

The attribute value determines the urgency of announcements: whether they should interrupt the user immediately (assertive), wait for a natural pause (polite), or not be announced at all (off).

Why Use Live Regions?

Without live regions, screen reader users wouldn't know about dynamic updates like status messages, notifications, error alerts, or real-time data changes. aria-live ensures these updates are communicated effectively.

Live Demo: aria-live Values

Waiting for notification...

Current mode: aria-live="polite"

Screen readers will announce when user pauses

Attribute Values

off(default)

Updates to the region will not be announced. This is the default when aria-live is not specified. Use when content changes but shouldn't interrupt users.

polite

Announcements are made at the next graceful opportunity, such as when the user pauses typing or finishes reading current content. Use for most status updates (form validation, notifications, progress updates).

Best for: Status messages, form feedback, non-critical updates
assertive

Announcements immediately interrupt the current screen reader output. Use sparingly - only for critical, time-sensitive information (errors, warnings, urgent alerts).

Best for: Critical errors, urgent warnings, time-sensitive alerts

Code Examples

polite

<!-- aria-live="polite" - Waits for user pause -->
<div role="status" 
     aria-live="polite" 
     aria-atomic="true">
  <p>Form saved successfully</p>
</div>

<!-- Screen reader announces when user pauses speaking or reading.
     Does not interrupt current announcement. -->

assertive

<!-- aria-live="assertive" - Interrupts immediately -->
<div role="alert" 
     aria-live="assertive" 
     aria-atomic="true">
  <p>Error: Connection lost. Trying to reconnect...</p>
</div>

<!-- Screen reader immediately interrupts to announce.
     Use sparingly for critical, time-sensitive information. -->

off

<!-- aria-live="off" - No announcements (default) -->
<div role="status" 
     aria-live="off">
  <p>This will not be announced</p>
</div>

<!-- Screen reader will not announce changes.
     Equivalent to not having a live region at all. -->

status Message

<!-- Status Messages (aria-live="polite") -->
<div id="form-status" 
     role="status" 
     aria-live="polite"
     aria-atomic="true">
  <!-- Messages appear here -->
</div>

<script>
  function showStatus(message, type) {
    const status = document.getElementById('form-status');
    status.innerHTML = `
      <div class="status-${type}">
        <span class="icon">${type === 'success' ? '✓' : '✗'}</span>
        <span>${message}</span>
      </div>
    `;
  }
  
  // Usage
  form.addEventListener('submit', async (e) => {
    e.preventDefault();
    try {
      await saveData(formData);
      showStatus('Form saved successfully', 'success');
    } catch (error) {
      showStatus('Save failed. Please try again.', 'error');
    }
  });
</script>

react

// React Component with aria-live
import { useState, useEffect } from 'react';

function LiveNotifications() {
  const [messages, setMessages] = useState([]);
  const [liveRegionMessage, setLiveRegionMessage] = useState('');
  
  const addMessage = (text, priority = 'polite') => {
    const newMessage = {
      id: Date.now(),
      text,
      priority,
      timestamp: new Date().toISOString(),
    };
    
    setMessages(prev => [...prev, newMessage]);
    
    // Update live region for screen readers
    setLiveRegionMessage(text);
    
    // Clear after announcement
    setTimeout(() => {
      setLiveRegionMessage('');
    }, 1000);
  };
  
  return (
    <div>
      {/* Live region for polite announcements */}
      <div
        role="status"
        aria-live="polite"
        aria-atomic="true"
        className="sr-only"
      >
        {liveRegionMessage}
      </div>
      
      {/* Visible message list */}
      <div className="message-list">
        {messages.map(msg => (
          <div key={msg.id} className="message">
            {msg.text}
          </div>
        ))}
      </div>
      
      <button onClick={() => addMessage('Item added to cart')}>
        Add to Cart
      </button>
    </div>
  );
}

// Chat Application Example
function ChatRoom() {
  const [messages, setMessages] = useState([]);
  const [newMessageAnnouncement, setNewMessageAnnouncement] = useState('');
  
  useEffect(() => {
    // Listen for new messages from WebSocket
    socket.on('message', (msg) => {
      setMessages(prev => [...prev, msg]);
      
      // Announce to screen readers
      setNewMessageAnnouncement(`New message from ${msg.author}: ${msg.text}`);
      setTimeout(() => setNewMessageAnnouncement(''), 1000);
    });
  }, []);
  
  return (
    <>
      {/* Live region for chat announcements */}
      <div
        role="log"
        aria-live="polite"
        aria-atomic="false"
        className="sr-only"
      >
        {newMessageAnnouncement}
      </div>
      
      {/* Chat messages */}
      <div className="chat-messages">
        {messages.map(msg => (
          <div key={msg.id}>
            <strong>{msg.author}:</strong> {msg.text}
          </div>
        ))}
      </div>
    </>
  );
}

Best Practices

Use aria-live="polite" for most status updates and notifications

Use aria-live="assertive" only for critical, time-sensitive alerts

Pair with aria-atomic to control announcement verbosity

Keep live region content concise and meaningful

Use appropriate ARIA roles (status, alert, log) instead of generic divs

Test with multiple screen readers (NVDA, JAWS, VoiceOver)

×

Don't overuse assertive - it's disruptive and annoying

×

Don't put large amounts of text in live regions

×

Don't create live regions that update too frequently

×

Don't use for decorative or non-essential updates

Implicit aria-live Values

Some ARIA roles have implicit aria-live values:

role="alert"aria-live="assertive"

Urgent messages

role="status"aria-live="polite"

Status information

role="log"aria-live="polite"

Chat logs, history

role="timer"aria-live="off"

Countdown timers

role="marquee"aria-live="off"

Non-essential updates

Accessibility Notes

Timing is Everything

polite announcements wait for natural breaks in speech or reading. This is less disruptive but may be delayed. assertive interrupts immediately but should only be used when delays could cause problems.

Screen Reader Overload

Too many live regions or overly frequent updates can overwhelm users. Limit the number of active live regions on a page, and combine related updates into a single announcement rather than multiple rapid-fire announcements.

Visual vs Screen Reader Content

Live regions can be visually hidden using sr-only CSS class while still announcing to screen readers. This is useful for announcements that don't need visual representation (e.g., "Item added to cart").

Related Attributes

Specifications & Resources