Skip to main content

β™Ώ Web Accessibility Fundamentals

Accessibility is not a feature you bolt on at the end β€” it is a quality of well-built HTML. This lesson gives you the mental model (the WCAG POUR principles) and the concrete practices that make your pages usable by people with visual, motor, auditory, and cognitive disabilities.

🎯 Learning Objectives

By the end of this lesson, you will be able to:

  • Explain the four WCAG POUR principles and the A / AA / AAA conformance levels
  • Describe how the accessibility tree is built from your HTML and why semantic markup matters
  • Write effective alt text and correctly label forms with <label>, <fieldset>, and <legend>
  • Ensure keyboard accessibility and preserve visible focus indicators
  • Meet color-contrast requirements and avoid color-only signalling
  • Run a basic accessibility audit using automated and manual techniques

Estimated Time: 35–45 minutes  β€’  Difficulty: Beginner–Intermediate

Hands-on: Audit and repair a broken contact form riddled with accessibility bugs.

In This Lesson

What Is Web Accessibility?

Web accessibility means designing sites and apps that everyone can use β€” including people with visual, auditory, motor, speech, cognitive, or neurological disabilities. It also helps people in temporary situations: a broken arm, bright sunlight, a noisy train, a slow connection.

πŸ’‘ A useful analogy: Accessibility is the web's version of building codes. A physical building needs ramps, elevators, wide doorways, and clear signage so everyone can get in and find their way. A website needs the digital equivalents β€” keyboard access, alt text, clear structure, sufficient contrast. And just like curb cuts, features built for disabled users end up helping everyone (parents with strollers, delivery workers, you at 2 a.m.).

Why accessibility matters

  • Ethical & inclusive β€” everyone deserves equal access to information and services.
  • Legal β€” laws like the ADA (US) and the European Accessibility Act require accessible digital services.
  • Larger audience β€” the WHO estimates about 16% of the world's population lives with a significant disability.
  • Better for everyone β€” accessible sites tend to be clearer, faster, and easier to use for all.
  • SEO overlap β€” many accessibility practices (headings, alt text, semantic structure) also boost search rankings.

The WCAG POUR Principles

The Web Content Accessibility Guidelines (WCAG) are the international standard. Everything in them hangs off four principles, remembered by the acronym POUR:

flowchart TD A["Accessible content
(WCAG Β· POUR)"] --> B[Perceivable] A --> C[Operable] A --> D[Understandable] A --> E[Robust] B --> B1["Can all users
perceive the content?"] C --> C1["Can all users
operate the interface?"] D --> D1["Is content and behavior
understandable?"] E --> E1["Does it work across
browsers & assistive tech?"]
PrincipleMeansExample failure
PerceivableUsers can perceive the informationAn image with no alt text
OperableUsers can operate the controlsA menu that only works with a mouse
UnderstandableContent and behavior are predictableA form that fails silently with no error message
RobustWorks across browsers and assistive techA custom widget that screen readers can't interpret

πŸ“– WCAG Conformance Levels

Level A: minimal β€” removes the biggest barriers.

Level AA: the practical target most laws and organisations require.

Level AAA: the highest bar β€” often applied to specific critical content, rarely site-wide.

HTML: The Foundation

Here is the most important fact in this whole lesson: HTML is accessible by default. A native <button>, a real <label>, a proper heading β€” all of them come with accessibility built in. Most accessibility bugs come from fighting HTML (rebuilding a button out of a <div>) rather than using it.

The semantic elements from the previous lesson are the backbone: screen readers announce headings and landmarks so users can navigate by structure, jumping straight to <main> or skimming the heading outline.

The Accessibility Tree

When a browser parses your HTML it builds two trees. The DOM tree drives visual rendering. The accessibility tree is a parallel structure β€” a stripped-down model of roles, names, and states β€” that assistive technologies read. Good HTML produces a good accessibility tree automatically.

flowchart TD A[HTML Document] --> B["DOM Tree
(visual rendering)"] A --> C["Accessibility Tree
(roles, names, states)"] B --> D[Sighted users] C --> E[Screen reader & AT users]

Think of the accessibility tree as a second, spoken version of your page. If your markup is meaningless, the spoken version is meaningless too.

Essential Practices

1. Language and page title

Two attributes do a lot of heavy lifting: the lang attribute tells screen readers which pronunciation rules to use, and a descriptive <title> orients users switching between tabs.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Contact Us β€” Acme Widgets</title>
</head>

2. Logical heading structure

Headings are the table of contents of your page. Screen-reader users pull up a list of them to navigate. Never skip levels for styling reasons, and never fake a heading with a big <div>.

βœ… Good β€” one h1, no skipped levels

<h1>Website Title</h1>
<section>
  <h2>Main Section</h2>
  <h3>Subsection</h3>
  <h3>Another Subsection</h3>
</section>

⚠️ Poor β€” skipped levels and fake headings

<div>Website Title</div>      <!-- not a heading at all -->
<h3>Main Section</h3>          <!-- skipped h2 -->
<h1>Subsection</h1>            <!-- second h1, out of order -->
<div class="big-bold">Another</div>  <!-- styled div, invisible to AT -->

3. Alternative text for images

Alt text is the spoken description of an image. The rule: describe the purpose, not the pixels. Decorative images take an empty alt="" so screen readers skip them entirely.

<!-- Informative: describe what the image communicates -->
<img src="/img/sales-2026.png"
     alt="Bar chart: sales grew 15% in Q1, 22% Q2, 18% Q3, 25% Q4 of 2026">

<!-- Decorative: empty alt so it is ignored -->
<img src="/img/divider.png" alt="">

<!-- Image is the only content of a link: describe the destination -->
<a href="/about">
  <img src="/img/about-icon.png" alt="About us">
</a>

Alt text is to images what audio description is to film: it narrates the visual so nobody misses the meaning.

4. Forms and labels

Every input needs a programmatically associated <label>. Grouped controls (like radio buttons) go inside a <fieldset> with a <legend>.

<form>
  <p>
    <label for="name">Name</label>
    <input type="text" id="name" name="name" required>
  </p>
  <p>
    <label for="email">Email</label>
    <input type="email" id="email" name="email" required>
  </p>

  <fieldset>
    <legend>Subscription Type</legend>
    <p>
      <input type="radio" id="basic" name="plan" value="basic">
      <label for="basic">Basic</label>
    </p>
    <p>
      <input type="radio" id="premium" name="plan" value="premium">
      <label for="premium">Premium</label>
    </p>
  </fieldset>

  <button type="submit">Subscribe</button>
</form>

The for attribute on each label must match the input's id. This also enlarges the click target β€” tapping the label focuses the field, which helps users with motor difficulties.

5. Links that make sense out of context

Screen-reader users often pull up a list of just the links on a page. "Click here" Γ—12 is useless in that list; descriptive link text is self-explanatory.

<!-- Good: text describes the destination -->
<p>Read about our <a href="/services">web development services</a>.</p>

<!-- Poor: "click here" tells a link list nothing -->
<p>To see our services, <a href="/services">click here</a>.</p>

Keyboard Accessibility

Many people navigate entirely by keyboard β€” users with motor disabilities, screen-reader users, and anyone whose mouse just died. The golden rule: anything you can do with a mouse must be possible with a keyboard.

  • Visible focus β€” the element with keyboard focus must be clearly outlined.
  • Logical tab order β€” Tab should move through controls in a sensible sequence (usually the DOM order).
  • No keyboard traps β€” users must be able to Tab out of every component.
  • Native elements win β€” <button> and <a href> are focusable and operable by default; a clickable <div> is not.

⚠️ Common trap: a div pretending to be a button

<!-- Broken: not focusable, no Enter/Space, invisible to AT -->
<div class="button" onclick="submitForm()">Submit</div>

<!-- Fixed: a real button does all of that for free -->
<button type="button" onclick="submitForm()">Submit</button>

Never delete focus styles

Removing the focus outline is one of the most damaging things you can do β€” keyboard users lose all sense of where they are. If the default outline clashes with your design, replace it, don't remove it.

/* Harmful β€” keyboard users can no longer see focus */
:focus { outline: none; }

/* Better β€” a clear, custom focus ring.
   :focus-visible targets keyboard focus without
   flashing an outline on every mouse click. */
:focus-visible {
  outline: 3px solid #4d90fe;
  outline-offset: 2px;
  border-radius: 3px;
}

Color and Contrast

Two rules govern color. First, never use color as the only signal β€” someone who is colorblind (about 1 in 12 men) must still get the message. Second, text must contrast enough with its background to be readable.

WCAG AA contrast minimums

  • Normal text: contrast ratio of at least 4.5:1
  • Large text (β‰₯ 18.66px bold, or β‰₯ 24px): at least 3:1
  • UI components and meaningful graphics: at least 3:1
Text contrast examples Three bars showing high, medium, and passing contrast ratios between text and background colors. High contrast β€” passes AA and AAA Solid contrast β€” passes AA Borderline β€” check with a contrast tool
Figure 1 β€” Aim for text that stays readable in both light and dark themes. When in doubt, run the pairing through a contrast checker.

πŸ’‘ Color plus a second cue

<!-- Poor: red is the only signal a field is required -->
<label style="color: red;">Name</label>

<!-- Better: color AND a visible, labelled indicator -->
<label for="name">Name <span class="req" aria-hidden="true">*</span></label>
<input type="text" id="name" required aria-required="true">

Testing for Accessibility

Automated tools catch roughly 30–40% of issues β€” the mechanical ones. The rest need a human. Use both.

AutomatedManual
Lighthouse (Chrome DevTools)Unplug the mouse β€” can you do everything?
axe DevToolsTurn on a screen reader (NVDA, VoiceOver)
WAVE evaluation toolZoom to 200% β€” does the layout survive?
HTML validatorDisable CSS β€” does the content still make sense in order?

βœ… A quick accessibility checklist

  • Logical heading structure, single <h1>
  • Every image has appropriate alt text (empty for decorative)
  • Color is never the only means of conveying information
  • Text meets the 4.5:1 contrast minimum
  • Every form control has an associated label
  • The whole page works with the keyboard alone
  • Focus is always visible
  • The <html> element has a lang attribute and the page has a descriptive title

Hands-on Exercise

πŸ‹οΈ Audit and Repair a Contact Form

Objective: Find every accessibility bug in this form, then rewrite it to be fully accessible.

Broken markup:

<div>
  <div style="font-size: 24px; font-weight: bold;">Contact Us</div>
  <div>
    Name
    <input type="text">
  </div>
  <div>
    Email
    <input type="text">
  </div>
  <div>
    <div style="color: red;">* Required Field</div>
    Message
    <textarea></textarea>
  </div>
  <div style="background: blue; color: white; padding: 10px;"
       onclick="submitForm()">SEND</div>
  <img src="/img/contact.jpg">
</div>
πŸ’‘ Hint β€” how many bugs can you spot?
  • The "Contact Us" heading is a styled div, not an <h1>.
  • No <label> is associated with any input.
  • The email field uses type="text" instead of type="email".
  • "Required" is signalled by color alone.
  • The SEND control is a clickable div β€” not focusable or keyboard-operable.
  • The image has no alt attribute.
βœ… Accessible rewrite
<section>
  <h1>Contact Us</h1>
  <p>Fields marked <span aria-hidden="true">*</span>
     (<span class="visually-hidden">required</span>) are required.</p>

  <form>
    <p>
      <label for="name">Name *</label>
      <input type="text" id="name" name="name" required aria-required="true">
    </p>
    <p>
      <label for="email">Email *</label>
      <input type="email" id="email" name="email" required aria-required="true">
    </p>
    <p>
      <label for="message">Message *</label>
      <textarea id="message" name="message" required aria-required="true"></textarea>
    </p>
    <button type="submit">Send</button>
  </form>

  <img src="/img/contact.jpg"
       alt="Our support team at their desks, ready to help">
</section>

Every input now has a real label, the email field validates its type, "required" is conveyed with text (not just color), and the button is a native <button> that any keyboard can reach.

🎯 Quick Quiz

Question 1: What does the acronym POUR stand for?

Question 2: What is the correct alt text for a purely decorative divider image?

Question 3: A designer asks you to remove the focus outline because it looks ugly. What should you do?

Summary & Quiz

πŸŽ‰ Key Takeaways

  • Accessibility benefits everyone and is both an ethical and often legal requirement.
  • The POUR principles β€” Perceivable, Operable, Understandable, Robust β€” organise all of WCAG; AA is the usual target.
  • Semantic HTML is the foundation: it builds a good accessibility tree for free.
  • Write purposeful alt text, label every form control, keep everything keyboard-operable with visible focus.
  • Never rely on color alone, and meet the 4.5:1 contrast minimum for normal text.
  • Test with a combination of automated tools and manual keyboard/screen-reader checks.

πŸ“š Further Reading

πŸš€ What's Next?

Semantic HTML handles most accessibility needs β€” but dynamic, custom widgets sometimes need more. Next, in ARIA Roles and Attributes, you'll learn how to fill the gaps that native HTML can't reach, and just as importantly, when not to.

πŸŽ‰ Well done!

You now build pages that work for every user β€” with a keyboard, a screen reader, or a bright sunny window.