HTML Accessibility (a11y)

Accessibility ensures everyone can use your site, including people using screen readers, keyboards, switch devices, and zoom/contrast settings. Start with semantic HTML, then support keyboard navigation, visible focus, clear labels and alt text, and only add ARIA when native semantics are not enough.

1) Landmarks & Heading Structure


<header>Site header & nav</header>
<main id="content">
  <h1>Page title</h1>
  <section aria-labelledby="sum">
    <h2 id="sum">Summary</h2>
    ...
  </section>
</main>
<footer>Site footer</footer>

  • Use one logical <h1> per page; nest h2, h3… in order.
  • Use semantic landmarks: <header>, <nav>, <main>, <aside>, <footer>.

2) Images & alt Text


<!-- Informative image -->
<img src="../asset/img/sample.jpg" alt="HTML5 logo">

<!-- Decorative image -->
<img src="decor.png" alt="" role="presentation">

  • Describe meaning, not appearance. If purely decorative, use alt="".
  • For complex charts, reference a nearby text description (e.g., aria-describedby).

4) Keyboard Navigation & Visible Focus


/* Keep a visible focus ring for keyboard users */
a, button, input:focus{ outline:3px solid #005fcc; outline-offset:2px; }

Focusable link
  • All functionality must be reachable via keyboard: Tab, Shift+Tab, Enter, Space.
  • Don’t remove outlines unless you provide a better visible focus style.
  • Provide a Skip to main content link (see top of page).

5) Forms, Labels & Messages


<label for="email">Email</label>
<input id="email" type="email" required autocomplete="email">

<!-- Help/error text association -->
<p id="emailHelp">We never share your email.</p>
<input aria-describedby="emailHelp">

<!-- Live region for async/validation messages -->
<div aria-live="polite" id="formStatus"></div>

  • Always pair inputs with visible <label> or a proper accessible name.
  • Link help and error text with aria-describedby.
  • Announce validation updates via an aria-live region.

6) ARIA Basics (Use only when needed)


<!-- Disclosure pattern -->
<button aria-expanded="false" aria-controls="ans1">Show Answer</button>
<div id="ans1" hidden>42</div>

Rule: Prefer native HTML elements first; add ARIA roles/states to fill gaps, not replace semantics.

7) Media: Captions & Transcripts


<video controls>
  <source src="movie.mp4" type="video/mp4">
  <track kind="captions" src="movie.en.vtt" srclang="en" label="English" default>
</video>

  • Provide captions for video, transcripts for audio.
  • Avoid autoplay with sound; use muted if autoplay is necessary.

8) Accessible Tables


<table>
  <caption>Monthly Sales</caption>
  <thead>
    <tr>
      <th scope="col">Month</th>
      <th scope="col">Revenue</th>
    </tr>
  </thead>
  <tbody>
    <tr><th scope="row">Jan</th><td>$10k</td></tr>
  </tbody>
</table>

  • Use <caption> to summarize the table.
  • Mark headers with <th scope="col|row"> for screen-reader association.

9) Color Contrast & Not Using Color Alone

Good: #FFFFFF text on #000000 (high contrast)
Poor: #AAAAAA text on #EEEEEE (low contrast)
  • Aim for WCAG contrast: 4.5:1 (normal text), 3:1 (large text ≥18px or 14px bold).
  • Don’t rely on color alone; add icons, patterns, or text.

10) Language & Direction


<html lang="en">
<p lang="hi">नमस्ते</p>
<p dir="rtl">مرحبا</p>

Set the correct language so screen readers pronounce text properly; use dir="rtl" for right-to-left scripts.

Quick Checklist:

  • Semantic landmarks and a logical heading outline.
  • Alt text for images (or empty alt for decorative).
  • Keyboard access with visible focus; include Skip link.
  • Form labels, clear help/error text, aria-live updates.
  • Captions/transcripts for media; avoid autoplay with sound.
  • Accessible tables with <caption> and proper <th> scopes.
  • Good color contrast; don’t rely on color alone.
  • Use ARIA minimally and correctly—never to replace native semantics.