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.
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.
politeAnnouncements 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).
assertiveAnnouncements immediately interrupt the current screen reader output. Use sparingly - only for critical, time-sensitive information (errors, warnings, urgent 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").