Accessibility Concepts · ARIA & Semantic HTML · Accessible Forms · Images, Media, Color & Motion
Accessibility is not a nice-to-have. Learn the WCAG framework (POUR), how screen readers consume your page, and the legal/business case. ARIA exists for cases where HTML semantics fall short. Use semantic HTML first; reach for ARIA only when needed. Master the basics: role, aria-label, aria-expanded. Forms are the most accessibility-critical part of your app. Pair labels properly, group with fieldset, announce errors clearly, and manage focus. Make images, video, color, and animation usable for everyone. Write meaningful alt text, caption video, hit contrast ratios, and respect reduced-motion preferences.
What you'll learn
- 1Explain WCAG and the four POUR principles
- 2Run a basic screen-reader test (VoiceOver, NVDA)
- 3Recognize common a11y wins (alt text, headings, focus)
- 4Use Lighthouse and axe-core for automated audits
- 5Apply the first rule of ARIA
- 6Use roles to describe widget purpose
- 7Announce dynamic state with aria-expanded, aria-checked
- 8Label icon-only buttons with aria-label
- 9Pair every input with a real <label>
- 10Group related inputs with <fieldset> + <legend>
- 11Show validation errors with aria-describedby and aria-invalid
- 12Move focus to the first error on submit
- 13Write alt text that conveys meaning, not just description
- 14Add captions and transcripts to video
- 15Meet WCAG AA contrast (4.5:1 for normal text)
- 16Respect prefers-reduced-motion
Accessibility Concepts
Accessibility is not a nice-to-have. Learn the WCAG framework (POUR), how screen readers consume your page, and the legal/business case.
1. Why Accessibility?
- ~15% of the world lives with a disability — your users
- Better a11y = better SEO and better usability for everyone
- Legally required in many countries (ADA, EAA)
- Costs almost nothing if built in from day one
2. POUR — The WCAG Pillars
| Principle | Means |
|---|---|
| Perceivable | Content can be perceived by sight, sound, or touch (alt text, captions, contrast) |
| Operable | All actions work with keyboard alone (no mouse-only menus) |
| Understandable | Predictable navigation, clear errors, plain language |
| Robust | Works with assistive technologies and future browsers |
3. WCAG Levels
- A — minimum
- AA — most regulations target this
- AAA — gold standard, rarely fully achievable site-wide
4. Quick Audit Tools
- Lighthouse (Chrome DevTools) — automated checks
- axe DevTools — deeper accessibility issues
- VoiceOver (macOS) Cmd+F5 / NVDA (Windows) — real screen-reader testing
- Tab through your site with the keyboard — focus order should make sense
Automated tools catch ~30% of issues. Always do a manual keyboard + screen-reader test before shipping.
ARIA & Semantic HTML
ARIA exists for cases where HTML semantics fall short. Use semantic HTML first; reach for ARIA only when needed. Master the basics: role, aria-label, aria-expanded.
1. The First Rule of ARIA
"If you can use a native HTML element instead of an ARIA role/property to achieve the same accessibility, do so." — W3C
<!-- Bad: re-implementing a button -->
<div role="button" tabindex="0" onclick="...">Click</div>
<!-- Good: just use a button -->
<button onclick="...">Click</button>2. Common Roles
| role | Use |
|---|---|
| banner | Top of page header |
| navigation | <nav> equivalent |
| main | <main> equivalent |
| contentinfo | <footer> equivalent |
| search | Search region |
| dialog | Modal dialog |
| alert | Time-sensitive notice (assertive) |
| status | Status update (polite) |
3. State & Properties
<!-- A toggle button -->
<button aria-pressed="false">Mute</button>
<!-- An accordion -->
<button aria-expanded="false" aria-controls="panel-1">FAQ</button>
<div id="panel-1" hidden>Answer...</div>
<!-- An icon-only button -->
<button aria-label="Close dialog">
<svg ...></svg>
</button>
<!-- A live region -->
<div role="status" aria-live="polite">3 items saved.</div>4. Landmarks Help Navigation
Screen-reader users press a shortcut to jump between landmarks. Semantic HTML (header/nav/main/footer) creates them for free.
Accessible Forms
Forms are the most accessibility-critical part of your app. Pair labels properly, group with fieldset, announce errors clearly, and manage focus.
1. Real Labels (not Placeholders)
<!-- Bad: placeholder is not a label -->
<input placeholder="Email">
<!-- Good: explicit label -->
<label for="email">Email</label>
<input id="email" name="email" type="email">
<!-- Or wrapped -->
<label>
Email
<input name="email" type="email">
</label>2. fieldset for Groups
<fieldset>
<legend>Shipping address</legend>
<label>Street <input name="street"></label>
<label>City <input name="city"></label>
</fieldset>
<fieldset>
<legend>Newsletter</legend>
<label><input type="radio" name="news" value="weekly"> Weekly</label>
<label><input type="radio" name="news" value="monthly"> Monthly</label>
</fieldset>3. Error Messages
<label for="pw">Password</label>
<input id="pw" type="password" aria-describedby="pw-help pw-err" aria-invalid="true">
<span id="pw-help">At least 8 characters.</span>
<span id="pw-err" role="alert">Password too short.</span>Show errors near the input, link them with aria-describedby, and announce them with role="alert".
4. Focus on Submit Error
function onSubmit(e) {
e.preventDefault();
const errors = validate(form);
if (errors.length) {
const first = form.querySelector(`[name="${errors[0].name}"]`);
first?.focus();
return;
}
// ... submit ...
}Images, Media, Color & Motion
Make images, video, color, and animation usable for everyone. Write meaningful alt text, caption video, hit contrast ratios, and respect reduced-motion preferences.
1. Alt Text That Helps
<!-- Informative image -->
<img src="chart.png" alt="Revenue grew from $1M in Q1 to $1.8M in Q3 2024">
<!-- Decorative — use empty alt to skip in screen readers -->
<img src="border.svg" alt="" aria-hidden="true">
<!-- Image is the link content -->
<a href="/profile"><img src="alice.jpg" alt="Alice — go to profile"></a>2. Video & Audio
<video controls>
<source src="demo.mp4" type="video/mp4">
<track kind="captions" src="demo.en.vtt" srclang="en" label="English">
</video>
<details><summary>Transcript</summary>
<p>[00:00] Welcome to the demo...</p>
</details>- Captions for hearing impaired
- Audio descriptions for blind users
- Transcripts help everyone (and SEO)
3. Color Contrast
| Text size | WCAG AA minimum |
|---|---|
| Normal text | 4.5:1 |
| Large text (18pt+ / 14pt+ bold) | 3:1 |
| UI components & graphics | 3:1 |
Never convey information by color alone. Use icons or text labels too.
4. Reduced Motion
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}Some users get nauseous from heavy animation. Respect their OS-level preference.
All lecture materials and example code are openly available on GitHub.
View on GitHub ↗Comments 0
No comments yet. Be the first.
Only members can comment.
Comments with ads, abuse, personal information or illegal content are hidden or removed. Comments are shown with your nickname. Privacy Policy