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.
HTML Accessibility (a11y)
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; nesth2,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).
3) Links vs Buttons
<!-- Navigation: link -->
<a href="/pricing">View pricing plans</a>
<!-- Action: button -->
<button type="button">Open menu</button>
Use links for navigation to a URL; use buttons for in-page actions.
4) Keyboard Navigation & Visible Focus
/* Keep a visible focus ring for keyboard users */
a, button, input:focus{ outline:3px solid #005fcc; outline-offset:2px; }
- 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-liveregion.
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
mutedif 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-liveupdates. - 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.