Advanced25 min read

Accessibility (a11y)

Learn how to make your web pages usable for everyone, including people who rely on screen readers, keyboard navigation, and other assistive technologies.

Why Accessibility Matters

Web accessibility (often abbreviated a11y — the "11" stands for the 11 letters between the "a" and the "y") means designing websites so that everyone can use them, regardless of ability or circumstance.

This includes people who are:

  • Blind or low-vision — using screen readers like VoiceOver, NVDA, or JAWS.
  • Motor-impaired — navigating entirely with a keyboard, switch device, or voice control.
  • Deaf or hard of hearing — relying on captions and transcripts.
  • Cognitively diverse — benefiting from clear structure and simple language.

Accessibility is not optional. In many regions it is a legal requirement (e.g., the ADA in the US, the EAA in the EU). More importantly, it is the right thing to do. An accessible site also tends to be better structured, more SEO-friendly, and easier to maintain.

ARIA Roles and Attributes

ARIA (Accessible Rich Internet Applications) is a set of attributes you can add to HTML elements to convey meaning to assistive technologies.

Common ARIA attributes

  • role — Overrides or supplements the element's native role. Example: <div role="navigation"> tells screen readers this div functions as a navigation landmark. Prefer semantic HTML (<nav>) when possible; use role only when you cannot.
  • aria-label — Provides an accessible name when visible text is missing. Example: <button aria-label="Close dialog">X</button>.
  • aria-describedby — Points to the id of another element that gives a longer description. Great for form helper text.
  • aria-hidden="true" — Hides an element from the accessibility tree while keeping it visually present. Useful for decorative icons.
  • aria-live — Announces dynamic content changes. Values: polite (waits for a pause) or assertive (interrupts immediately).

First rule of ARIA: Do not use ARIA if a native HTML element already communicates the same thing. <nav> is always better than <div role="navigation">.

Skip Navigation and Accessible Forms

html
<!-- Skip-to-content link: hidden until focused via keyboard -->
<a href="#main-content" class="skip-link">Skip to main content</a>

<nav aria-label="Primary navigation">
  <ul>
    <li><a href="/">Home</a></li>
    <li><a href="/about">About</a></li>
    <li><a href="/contact">Contact</a></li>
  </ul>
</nav>

<main id="main-content">
  <h1>Contact Us</h1>

  <form>
    <label for="email">Email address</label>
    <input
      type="email"
      id="email"
      name="email"
      aria-describedby="email-help"
      required
    >
    <small id="email-help">
      We will never share your email with anyone else.
    </small>

    <button type="submit">Send</button>
  </form>
</main>

Keyboard Navigation and Best Practices

Many users navigate entirely with the keyboard using Tab to move between focusable elements and Enter or Space to activate them.

Key practices

  1. Use native interactive elements. Buttons, links, and form controls are focusable by default. If you make a <div> clickable, keyboard users cannot reach it unless you add tabindex="0" and handle key events — which is fragile. Just use a <button>.
  2. Visible focus indicators. Never remove the outline on focused elements (outline: none) without providing an equally visible alternative.
  3. Logical tab order. The DOM order should match the visual order. Avoid using tabindex values greater than 0 — they create confusing tab sequences.
  4. Alt text on images. Every <img> needs an alt attribute. If the image is decorative, use alt="" (empty) so screen readers skip it. If the image conveys information, describe its meaning, not its appearance.
  5. Skip navigation link. Place a link at the very top of the page that jumps to the main content. This saves keyboard and screen-reader users from tabbing through the entire navigation on every page load.

When should you use `aria-hidden="true"` on an element?

Ready to practice?

Create your free account to access the interactive code editor, run challenges, and track your progress.