βΏ 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:
(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?"]
| Principle | Means | Example failure |
|---|---|---|
| Perceivable | Users can perceive the information | An image with no alt text |
| Operable | Users can operate the controls | A menu that only works with a mouse |
| Understandable | Content and behavior are predictable | A form that fails silently with no error message |
| Robust | Works across browsers and assistive tech | A 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.
(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
π‘ 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.
| Automated | Manual |
|---|---|
| Lighthouse (Chrome DevTools) | Unplug the mouse β can you do everything? |
| axe DevTools | Turn on a screen reader (NVDA, VoiceOver) |
| WAVE evaluation tool | Zoom to 200% β does the layout survive? |
| HTML validator | Disable 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 alangattribute 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 oftype="email". - "Required" is signalled by color alone.
- The SEND control is a clickable div β not focusable or keyboard-operable.
- The image has no
altattribute.
β 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
- WCAG 2.1 Quick Reference
- WebAIM β Web Accessibility In Mind
- MDN β Accessibility
- The A11Y Project
π 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.