HTML Accessibility

Accessibility means making web pages usable for everyone — including people who use screen readers, keyboard navigation, or other assistive tools due to visual, physical, or cognitive differences. Good HTML accessibility also improves SEO and benefits all users, not just those with disabilities.

Who Benefits from Accessibility

Visual Diagram — Types of Users

All Website Visitors
        |
        ├── Sighted users using a mouse or touch
        ├── Blind users using a screen reader
        ├── Low-vision users using zoom or high contrast
        ├── Deaf users needing captions on videos
        ├── Motor-impaired users using keyboard only
        ├── Users with cognitive differences
        └── Slow-connection users (accessibility helps them too)

Accessible HTML reaches all of these groups at once.

The alt Attribute on Images

Screen readers cannot see images. The alt attribute provides a text description that screen readers read aloud in place of the image.

<!-- Descriptive alt text -->
<img src="html-structure-diagram.png" alt="Diagram showing the nested structure of an HTML document with html, head, and body tags">

<!-- Decorative image — empty alt so screen reader skips it -->
<img src="decorative-line.png" alt="">

Rules for Good alt Text

Image Type            What to Write
--------------        ------------------------------------------
Informational image   Describe what the image shows
Linked image          Describe the link destination ("Go to homepage")
Chart or graph        Summarize the key data point it shows
Decorative image      Write alt="" (empty) — screen reader skips it
Logo with text        Include the company name in the alt text

Semantic HTML Tags

Semantic tags communicate the meaning of content to assistive technology. A screen reader reads <h1> and announces "Heading level 1". It reads <nav> and announces "Navigation". It reads <div> and says nothing extra — a div has no meaning.

<!-- Not accessible: no structure information -->
<div class="header">My Site</div>
<div class="nav">Home | About | Contact</div>

<!-- Accessible: structure is clear -->
<header>My Site</header>
<nav>
  <a href="/">Home</a>
  <a href="/about">About</a>
  <a href="/contact">Contact</a>
</nav>

Heading Hierarchy

Screen reader users navigate pages by jumping between headings. Use heading levels in the correct order — one <h1> per page, then <h2> for main sections, <h3> for subsections, and so on. Never skip levels.

Visual Diagram — Correct vs Incorrect Heading Structure

Correct structure (like a book outline):
  H1: HTML Tutorial
    H2: HTML Basics
      H3: Tags
      H3: Elements
    H2: HTML Forms
      H3: Input Types

Wrong structure (skips levels — confuses screen readers):
  H1: HTML Tutorial
    H3: Tags        ← skipped H2
      H5: Examples  ← skipped H4

Labels for Form Fields

Every form input needs a visible label. Screen readers announce the label when the user focuses on the input. Without a label, the user does not know what the field is for.

<!-- Correct: label connected via for + id -->
<label for="email">Email Address</label>
<input type="email" id="email" name="email">

<!-- Also correct: label wraps the input -->
<label>
  Phone Number
  <input type="tel" name="phone">
</label>

<!-- Wrong: placeholder is not a label replacement -->
<input type="email" name="email" placeholder="Email Address">

Placeholder text disappears when the user starts typing. If the placeholder is the only label, the user forgets what the field is for by the time they finish typing.

Keyboard Navigation

Many users navigate web pages using only the keyboard — pressing Tab to move between interactive elements, Enter to activate links and buttons, and arrow keys to move within components.

HTML elements that receive keyboard focus by default:

<a href="...">         → links
<button>               → buttons
<input>                → form fields
<select>               → dropdowns
<textarea>             → text areas

Non-interactive elements like <div> and <span> do not receive focus. When you make a <div> clickable with JavaScript, add tabindex="0" so keyboard users can reach it too.

<div tabindex="0" role="button" onclick="doSomething()">Click Me</div>

The tabindex Attribute

The tabindex attribute controls whether and in what order an element receives keyboard focus.

tabindex="0"   → element joins the natural tab order
tabindex="-1"  → element can be focused by JavaScript but not by Tab key
tabindex="1"   → element comes first in tab order (avoid — causes confusion)

Setting positive tabindex values like tabindex="3" overrides the natural order and confuses users. Use tabindex="0" for elements that should be reachable and tabindex="-1" for elements you manage programmatically.

ARIA Roles and Attributes

ARIA (Accessible Rich Internet Applications) attributes add accessibility information to HTML elements when native semantic tags are not enough.

role Attribute

The role attribute tells assistive technology what an element is.

<div role="navigation">...</div>    → same meaning as <nav>
<div role="main">...</div>          → same meaning as <main>
<div role="button">...</div>        → acts like a button
<div role="alert">Error!</div>      → screen reader announces immediately

aria-label Attribute

The aria-label attribute provides a text name for an element when no visible text label exists.

<button aria-label="Close dialog">✕</button>

Without aria-label, the screen reader would just say "button" with no further information. With it, the reader says "Close dialog, button."

aria-labelledby Attribute

When a visible heading or text already describes an element, reference that text with aria-labelledby instead of repeating it in aria-label.

<h2 id="contact-heading">Contact Form</h2>
<form aria-labelledby="contact-heading">
  ...
</form>

aria-hidden Attribute

The aria-hidden="true" attribute hides an element from screen readers while keeping it visible on screen. Use it for decorative icons or duplicate text that would confuse screen reader users.

<button>
  <span aria-hidden="true">🔍</span>
  Search
</button>

Without aria-hidden, the screen reader would say "magnifying glass emoji Search button." With it, the reader says only "Search button."

aria-expanded Attribute

Use aria-expanded on buttons that control collapsible content. Set it to "true" when the content is open and "false" when closed.

<button aria-expanded="false" aria-controls="menu">Menu</button>
<ul id="menu" hidden>
  <li><a href="/">Home</a></li>
</ul>

Color Contrast

Text must have sufficient contrast against its background so users with low vision can read it. The WCAG standard requires a contrast ratio of at least 4.5:1 for normal text and 3:1 for large text.

Visual Diagram — Contrast Examples

Hard to read (low contrast):
  Light gray text on white background → BAD
  Yellow text on white background → BAD

Easy to read (high contrast):
  Black text on white background → GOOD
  White text on dark blue background → GOOD
  Dark text on light yellow background → GOOD

Free online tools like the WebAIM Contrast Checker let you test any foreground and background color combination and show whether it passes WCAG requirements.

Skip Navigation Link

A skip link is a hidden link at the very top of a page that lets keyboard users jump directly to the main content, bypassing the navigation menu. Without it, keyboard users must press Tab many times through every navigation link on every page they visit.

<a href="#main-content" style="position:absolute; left:-9999px;">
  Skip to main content
</a>

<nav>...</nav>

<main id="main-content">
  ...
</main>

The link is invisible until a keyboard user presses Tab once — then it appears, allowing them to jump past the navigation with a single press of Enter.

Video and Audio Accessibility

Videos need captions for deaf users. Audio content needs transcripts. The <track> element adds captions or subtitles to a <video> element.

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

Accessibility Quick Checklist

✓ All images have descriptive alt text (or alt="" if decorative)
✓ Headings follow correct order: H1 → H2 → H3
✓ Every form input has a <label>
✓ Color contrast passes WCAG 4.5:1 ratio
✓ All interactive elements reachable by keyboard
✓ Videos have captions
✓ Skip navigation link at top of page
✓ Semantic HTML used throughout (header, nav, main, etc.)

Accessibility is not a checklist to complete at the end — it is a way of writing HTML from the start. Accessible pages rank better in search engines, work on more devices, and serve every visitor, regardless of how they experience the web.

Leave a Comment

Your email address will not be published. Required fields are marked *