Accessibility

Course 2 · Ch 6
Accessibility (a11y) Fundamentals
ARIA roles, landmarks, and a deliberate consolidation of the alt-text/accessibility habits introduced piece by piece across Course 1

Accessibility hasn't been a separate topic in this series — it's been woven into nearly every chapter so far (alt text in Ch5, label/for in Ch7, scope in tables Ch6, semantic landmarks in Ch8). This chapter consolidates that into a deliberate, named topic, and introduces ARIA — the toolkit for the cases semantic HTML alone doesn't fully cover.

The First Rule of ARIA: Don't Use ARIA If You Don't Need To

This sounds counterintuitive in a chapter about ARIA, but it's the single most important guideline in the whole topic: a native HTML element with correct built-in semantics is almost always better than a generic element with ARIA attributes bolted on.

⚠️
More work, more risk
<div role="button" tabindex="0" onclick="..."> — needs manual keyboard handling, manual focus styling, manual Enter/Space key support, and is easy to get subtly wrong.
Correct by default
<button> — keyboard accessibility, focus handling, and correct screen reader announcement all come built in, for free, automatically.

ARIA Landmark Roles — Reinforcing Semantic HTML

Fundamentals Chapter 8's semantic elements (header, nav, main, footer) already carry implicit ARIA landmark roles automatically — this is exactly why using real semantic tags is preferable to adding roles manually onto generic divs.

// Already has an implicit role of "navigation" — no extra ARIA needed <nav>...</nav> // Only needed when a genuinely non-semantic element must serve a landmark role <div role="navigation">...</div>

ARIA Attributes That Genuinely Add Value

aria-label
Provides an accessible name when visible text alone isn't descriptive enough — e.g. an icon-only close button.
aria-describedby
Points to another element's id whose text serves as additional description — useful for linking a form field to detailed help text beyond its label.
aria-hidden="true"
Hides a purely decorative element from screen readers entirely — for icons that add no information beyond what's already conveyed in text nearby.
aria-expanded
Communicates whether a collapsible element (an accordion, a dropdown menu) is currently open or closed — toggled via JavaScript as the state changes.
aria-live="polite"
Announces dynamically updated content (a "3 new messages" counter, a form validation message appearing) without interrupting whatever the screen reader is currently reading.
// Icon-only button — aria-label provides the accessible name <button aria-label="Close dialog"></button> // Decorative icon next to text that already says the same thing <button> <svg aria-hidden="true">...</svg> Delete item </button>

Revisiting alt Text — Practical Guidance, Consolidated

Fundamentals Chapter 5 introduced the basics; here's the consolidated practical guidance worth internalising properly:

  • Describe content and function, not appearance. "Submit form" not "blue rectangular button," unless the visual styling itself is genuinely the relevant information.
  • Don't repeat information already in adjacent text. If a caption already says "Philip's Raspberry Pi setup," the image's alt doesn't need to repeat it verbatim.
  • For complex images (charts, diagrams), summarise the key takeaway rather than attempting to describe every visual detail exhaustively — "Bar chart showing 23% growth in Q3" beats a literal pixel-by-pixel description.
  • For purely decorative images, alt="" (Fundamentals Chapter 5's rule, repeated because it matters) — not a missing attribute, an explicit empty one.

Keyboard Accessibility — The Test Most Sites Fail Silently

A genuinely accessible page can be fully operated using only the Tab, Enter, and Space keys — no mouse at all. The fastest practical check: unplug the mouse (or just don't touch it) and try to use the entire page with the keyboard alone.

A visible focus indicator must never be removed without a genuinely good replacement
* { outline: none; } in CSS (sometimes added purely to "clean up" the visual look) removes the only visible signal of which element currently has keyboard focus — leaving keyboard users with no way to tell where they are on the page at all. If the default focus outline's appearance is genuinely undesirable, replace it with a custom, clearly visible style — never simply remove it.

Testing Accessibility in Practice

  • Browser DevTools' Accessibility panel shows the computed accessible name, role, and properties for any selected element — directly verifies what a screen reader would actually announce.
  • Automated checkers (Lighthouse, axe) catch a meaningful subset of issues automatically — missing alt text, insufficient colour contrast, missing form labels.
  • Manual keyboard-only testing catches what automated tools generally can't — genuinely logical tab order, working focus management in custom widgets.
Automated tools catch maybe a third of real accessibility issues — manual testing still matters
Lighthouse and axe are genuinely valuable first-pass tools, but they can only catch programmatically detectable issues (a missing attribute, insufficient contrast) — they cannot judge whether alt text is actually meaningful, or whether a custom widget's keyboard behaviour genuinely makes sense to use. Treat automated checks as a floor, not a ceiling.

Chapter 6 Quick Reference

  • First rule of ARIA: a correct native element beats ARIA-on-a-div almost every time
  • Semantic HTML landmarks (Fundamentals Ch8) already carry implicit ARIA roles — no extra work needed
  • aria-label/aria-describedby/aria-hidden/aria-expanded/aria-live — genuinely valuable when native HTML can't express the needed meaning alone
  • alt text: describe content/function not appearance, don't repeat adjacent text, summarise complex images, empty alt for decorative ones
  • Keyboard test: can the entire page be operated with Tab/Enter/Space alone?
  • Never remove the focus outline without a clear custom replacement
  • Automated tools (Lighthouse/axe) catch a floor of issues, not the full picture — manual testing still matters
  • Next chapter: data attributes & custom attributes