Web Accessibility Fundamentals
1. Introduction
Web accessibility ensures websites and applications are usable by everyone โ including people with visual, auditory, motor, cognitive, or neurological disabilities. Approximately 1 in 6 people worldwide live with a disability. Beyond the ethical imperative, accessibility is increasingly a legal requirement (WCAG 2.1 is referenced in UK, EU, and US legislation). This lesson establishes the core principles, standards, and testing mindset every HTML developer must have.
2. Concept
WCAG 2.1 Conformance Levels
| Level | Description | Legal Requirement |
|---|---|---|
| A | Minimum โ removes the most critical barriers | Required by most accessibility laws |
| AA | Standard โ practical target for most websites | Required by EN 301 549 (EU), EAA, Section 508 (US) |
| AAA | Enhanced โ not required for entire sites | Aspirational / specialist contexts only |
3. Basic Example
<!DOCTYPE html>
<html lang="en"> <!-- lang is WCAG 3.1.1 Level A -->
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Accessibility Demo</title>
<style>
/* Visible focus indicator โ WCAG 2.4.7 Level AA */
:focus-visible {
outline: 3px solid #0070f3;
outline-offset: 2px;
}
/* Skip link โ visible only on keyboard focus */
.skip-link {
position: absolute;
left: -9999px;
top: auto;
width: 1px;
height: 1px;
overflow: hidden;
}
.skip-link:focus {
position: static;
width: auto;
height: auto;
overflow: visible;
background: #000;
color: #fff;
padding: 0.5em 1em;
z-index: 100;
}
</style>
</head>
<body>
<!-- Skip navigation: WCAG 2.4.1 Level A -->
<a href="#main-content" class="skip-link">Skip to main content</a>
<header>
<nav aria-label="Primary navigation">
<a href="/">Home</a>
<a href="/about">About</a>
<a href="/contact">Contact</a>
</nav>
</header>
<main id="main-content" tabindex="-1">
<h1>Accessibility Best Practices</h1>
<!-- Sufficient colour contrast: WCAG 1.4.3 Level AA -->
<p>Text must have a minimum contrast ratio of 4.5:1 against its background for normal text sizes.</p>
<!-- Descriptive alt text: WCAG 1.1.1 Level A -->
<img
src="/diagram.png"
alt="Flowchart: user submits form, server validates input, response returned"
width="600" height="300"
>
<!-- Native button โ keyboard accessible by default -->
<button type="button">Open Settings</button>
</main>
</body>
</html>
4. How It Works
Step 1 โ lang Attribute (WCAG 3.1.1 Level A)
Declaring lang="en" on <html> allows screen readers to choose the correct speech synthesis voice and pronunciation rules. Without it, foreign words and abbreviations may be read unintelligibly, creating a confusing experience.
Step 2 โ Skip Navigation (WCAG 2.4.1 Level A)
Keyboard users must Tab through every navigation link on every page load without a skip link. The skip link jumps to #main-content, which has tabindex="-1" to allow programmatic focus without appearing in the natural tab order.
Step 3 โ Colour Contrast (WCAG 1.4.3 Level AA)
Normal text (under 18pt / 14pt bold) needs at least a 4.5:1 contrast ratio between foreground and background. Large text needs 3:1. Use the WebAIM Contrast Checker or browser devtools accessibility panel to verify every text/background combination.
Step 4 โ Native Elements Over Custom Widgets
A <button> is focusable, activatable with Enter and Space, announced as “button” by screen readers, and styleable with CSS. A <div> has none of this by default. Always prefer native semantic elements โ they provide keyboard, mouse, touch, and assistive technology support for free.
5. Real-World Example
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Accessible News Article</title>
<style>
body { font-size: 1rem; line-height: 1.6; color: #1a1a1a; background: #fff; }
a { color: #0052cc; }
:focus-visible { outline: 3px solid #0052cc; outline-offset: 2px; }
.skip-link { position: absolute; left: -9999px; }
.skip-link:focus { position: static; background: #000; color: #fff; padding: .5em 1em; }
</style>
</head>
<body>
<a href="#article" class="skip-link">Skip to article</a>
<header>
<nav aria-label="Main navigation">
<a href="/">Home</a>
<a href="/news">News</a>
<a href="/tech">Tech</a>
</nav>
</header>
<main>
<article id="article" tabindex="-1">
<h1>UK Passes Landmark Accessibility Regulations</h1>
<p>Published <time datetime="2025-03-10">10 March 2025</time> by <a href="/authors/sam-jones">Sam Jones</a></p>
<figure>
<img
src="/images/parliament.jpg"
alt="The Houses of Parliament in London at dusk, lit from below"
width="800" height="450" loading="lazy"
>
<figcaption>The UK Parliament passed the legislation with cross-party support.</figcaption>
</figure>
<p>New regulations require all public sector websites to conform to WCAG 2.1 Level AA by end of 2025, with private sector organisations of 50+ employees subject to rules from 2026.</p>
<p>The <abbr title="Web Content Accessibility Guidelines">WCAG</abbr> criteria cover four principles: perceivable, operable, understandable, and robust.</p>
</article>
<aside aria-label="Related articles">
<h2>Related</h2>
<ul>
<li><a href="/wcag3">What Is WCAG 3.0?</a></li>
<li><a href="/screen-reader-stats">Screen Reader Survey 2025</a></li>
</ul>
</aside>
</main>
<footer>
<p>© 2025 NewsHub. <a href="/accessibility-statement">Accessibility Statement</a></p>
</footer>
</body>
</html>
6. Common Mistakes
❌ Removing focus outline (breaks keyboard navigation entirely)
<style>
* { outline: none; } /* destroys keyboard accessibility */
</style>
✓ Use :focus-visible to style โ never remove โ focus indicators
<style>
:focus-visible { outline: 3px solid #0070f3; outline-offset: 2px; }
</style>
❌ Missing lang attribute โ screen reader picks wrong voice
<html>
✓ Always declare the page language
<html lang="en">
7. Try It Yourself
▶ Test with WAVE Accessibility Tool
8. Quick Reference
| WCAG Criterion | Level | HTML Fix |
|---|---|---|
| 1.1.1 Non-text Content | A | Alt text on all informative images |
| 1.4.3 Contrast (Minimum) | AA | 4.5:1 ratio for normal text |
| 2.1.1 Keyboard | A | All functionality operable via keyboard |
| 2.4.1 Bypass Blocks | A | Skip navigation link |
| 2.4.7 Focus Visible | AA | Visible :focus-visible styles |
| 3.1.1 Language of Page | A | lang attribute on <html> |
| 4.1.2 Name, Role, Value | A | Semantic elements or correct ARIA |