Loading Developer Playground

Loading ...

Skip to main content
ARIA ROLELive Region Roles

status

A type of live region whose content is advisory information for the user but is not important enough to justify an alert. Status messages are announced politely without interrupting.

Implicit aria-live
polite
Implicit aria-atomic
true
Required Attributes
None

Overview

The status role creates a live region for advisory information. Unlike alerts, status messages are announced politely at the next opportune moment without interrupting the user.

This role is perfect for success messages, progress updates, and informational notifications that enhance the user experience but aren't critical.

When to Use Status vs Alert

status: "File saved successfully", "3 items in cart"
alert: "Connection lost!", "Payment failed"

Live Demo: Status Messages

No status updates yet...

Current cart: 0 items

Status messages are announced politely - they wait for you to pause before interrupting.

Implicit Attributes

The status role automatically sets:

aria-live="polite"

Status messages wait for a natural pause before being announced. They don't interrupt current screen reader output.

aria-atomic="true"

The entire status region is announced, providing full context rather than just the changed part.

Code Examples

Basic Status

<!-- Basic Status Message -->
<div role="status">
  <p>Loading data, please wait...</p>
</div>

<!-- Implicit aria-live="polite" means it waits for natural pause -->

Form Feedback

<!-- Form Submission Status -->
<form id="signup-form">
  <input type="email" name="email" required />
  <input type="password" name="password" required />
  <button type="submit">Sign Up</button>
</form>

<!-- Status region for feedback -->
<div id="form-status" role="status" aria-atomic="true">
  <!-- Status messages appear here -->
</div>

<script>
  const form = document.getElementById('signup-form');
  const status = document.getElementById('form-status');
  
  form.addEventListener('submit', async (e) => {
    e.preventDefault();
    
    // Show processing status
    status.textContent = 'Creating your account...';
    
    try {
      await createAccount(formData);
      status.textContent = 'Account created successfully!';
    } catch (error) {
      status.textContent = 'Sign up failed. Please try again.';
    }
  });
</script>

Shopping Cart

<!-- Shopping Cart Status -->
<div id="cart-status" role="status" aria-atomic="true" aria-live="polite">
  <!-- Cart updates announced here -->
</div>

<script>
  function addToCart(product) {
    cart.add(product);
    
    const status = document.getElementById('cart-status');
    status.textContent = `${product.name} added to cart. ${cart.length} items total.`;
    
    // Status will be announced when user pauses
  }
  
  function removeFromCart(productId) {
    const product = cart.find(productId);
    cart.remove(productId);
    
    const status = document.getElementById('cart-status');
    status.textContent = `${product.name} removed from cart. ${cart.length} items remaining.`;
  }
</script>

React Component

// React Status Component
import { useState, useCallback } from 'react';

function StatusMessage({ message, type = 'info', duration = 5000 }) {
  const [isVisible, setIsVisible] = useState(!!message);
  
  useEffect(() => {
    if (message) {
      setIsVisible(true);
      const timer = setTimeout(() => {
        setIsVisible(false);
      }, duration);
      return () => clearTimeout(timer);
    }
  }, [message, duration]);
  
  if (!isVisible) return null;
  
  return (
    <div
      role="status"
      aria-atomic="true"
      className={`status status-${type}`}
    >
      {message}
    </div>
  );
}

// Usage Example
function FileUpload() {
  const [status, setStatus] = useState('');
  const [uploading, setUploading] = useState(false);
  
  const handleUpload = async (file) => {
    setUploading(true);
    setStatus('Uploading file...');
    
    try {
      const result = await uploadFile(file);
      setStatus(`File "${file.name}" uploaded successfully`);
    } catch (error) {
      setStatus(`Upload failed: ${error.message}`);
    } finally {
      setUploading(false);
    }
  };
  
  return (
    <div>
      <input
        type="file"
        onChange={(e) => handleUpload(e.target.files[0])}
        disabled={uploading}
      />
      
      <StatusMessage message={status} type="info" />
    </div>
  );
}

Best Practices

Use for success messages and confirmations

Use for loading states and progress updates

Use for shopping cart updates and item counts

Use for search result counts and filter updates

Keep messages brief and informative

Combine with aria-atomic="true" for context

×

Don't use for critical errors - use role="alert" instead

×

Don't update status too frequently - it's annoying

×

Don't use for decorative or non-informative content

×

Don't forget to clear status messages after use

Common Use Cases

Form submission feedback
File upload progress
Search result counts
Shopping cart updates
Filter result updates
Save confirmations
Loading indicators
Character/word counts
Password strength meters
Autocomplete suggestions count

Accessibility Notes

Polite Announcements

Status messages have aria-live="polite" implicitly set. They wait for the user to finish their current task or pause before being announced. This makes them less disruptive than alerts.

Visual and Auditory Parity

Ensure status messages are visible to sighted users as well. Don't hide them with display:none or sr-only classes. Both sighted and blind users benefit from status feedback.

Related Roles

Specifications & Resources