React - Accessibility Essentials

Overview

Estimated time: 20–30 minutes

Improve keyboard navigation and screen reader support with skip links, ARIA attributes, and live region announcements.

Try it: Skip link, collapsible with ARIA, and aria-live updates

View source
function A11yDemo(){
  const mainRef = React.useRef(null);
  const [open, setOpen] = React.useState(false);
  const [count, setCount] = React.useState(0);
  function skipToMain(e){ e.preventDefault(); if (mainRef.current) mainRef.current.focus(); }
  return (
    <div>
      <a href="#main" onClick={skipToMain} style={{position:'absolute', left:-9999}} onFocus={e => e.currentTarget.style.left='8px'} onBlur={e => e.currentTarget.style.left='-9999px'}>Skip to content</a>
      <button aria-expanded={open} aria-controls="sect" onClick={() => setOpen(o => !o)}>{open ? 'Hide' : 'Show'} details</button>
      <section id="sect" hidden={!open}>
        <p>This is a collapsible section. Toggle button updates aria-expanded.</p>
      </section>
      <main id="main" ref={mainRef} tabIndex={-1} style={{outline:'none', display:'block', marginTop:8}}>
        <h3>Main content</h3>
        <button onClick={() => setCount(c => c+1)}>Add notification</button>
        <div aria-live="polite" style={{marginTop:8}}>{count ? `Notifications: ${count}` : ''}</div>
      </main>
    </div>
  );
}
ReactDOM.createRoot(document.getElementById('try-a11y')).render(<A11yDemo />);

Syntax primer

  • Skip link: jump focus to main content; show link on focus.
  • ARIA: aria-expanded/aria-controls for toggles; aria-live for announcements.

Common pitfalls

  • Missing keyboard focus styles—ensure focus is visible.
  • Toggle content without updating ARIA—keep attributes in sync.

Checks for Understanding

  1. What does aria-expanded indicate on a toggle button?
  2. Why is a skip link useful, and when should it be visible?
Show answers
  1. Whether the controlled region is expanded (true) or collapsed (false), enabling screen readers to announce state.
  2. It provides keyboard users a quick jump to main content; it should become visible on focus.

Exercises

  1. Add an aria-label to the toggle button and verify screen reader announcement.
  2. Introduce a dismissible alert region using role="alert" and test keyboard and screen reader behavior.
  3. Ensure focus is moved to the first heading inside the newly shown section when it expands.