Audit a broken landing page and fix five WCAG failures with the smallest correct changes.
Why this matters
This lesson puts the whole course together. Real accessibility work usually starts with an existing page full of problems, a deadline, and no time to rebuild it. The skill is to find the issues quickly, fix the ones that matter most with the smallest correct change, and verify each fix. Developers do this in bug-fix tickets; designers do it when reviewing a build against the design; both do it in audits.
A five-minute audit routine
Use the same order every time. It moves from the cheapest checks to the most effort.
- Automated scan. axe or Lighthouse (Lesson 1). Note the issues.
- Page basics. Is there a
langon<html>(3.1.1)? A specific<title>(2.4.2)? One<h1>and no skipped heading levels (1.3.1)? - Keyboard. Tab through everything. Is focus visible (2.4.7)? Can you reach and operate every control (2.1.1)? Is there a skip link (2.4.1)?
- Names. Every image has a fitting
alt(1.1.1); every input has a label (3.3.2, 4.1.2); every button and link has text that makes sense (2.4.4). - Colour. Text contrast at least 4.5:1, large text 3:1 (1.4.3); nothing relies on colour alone (1.4.1).
- Zoom and reflow. 200 percent text zoom and a 320 px wide window (1.4.4, 1.4.10).
- Motion. Animations respect
prefers-reduced-motion, nothing flashes more than three times a second (2.3.1), and anything that moves on its own for more than five seconds can be paused (2.2.2). - Screen reader spot check on the key task (Lesson 2).
Fixing contrast properly
Contrast ratio compares the relative luminance of two colours, from 1:1 (same colour) to 21:1 (black on white). You do not need to calculate it by hand; DevTools shows the ratio in the colour picker when you inspect text, and suggests a passing colour. For reference, the formula from WCAG is:
// sRGB channel (0-255) to linear light
const lin = c => { c /= 255; return c <= 0.03928 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4; };
const lum = ([r, g, b]) => 0.2126 * lin(r) + 0.7152 * lin(g) + 0.0722 * lin(b);
const ratio = (a, b) => { const [hi, lo] = [lum(a), lum(b)].sort((x, y) => y - x); return (hi + 0.05) / (lo + 0.05); };
ratio([153, 153, 153], [255, 255, 255]); // #999 on white: about 2.85, fails
ratio([89, 89, 89], [255, 255, 255]); // #595959 on white: about 7.0, passes AA and AAA
Fix contrast in the design tokens (one CSS custom property), not element by element, so every use improves at once. Remember to check hover, focus, disabled and placeholder states, and text on images.
Reduced motion
Some people get dizzy or nauseous from parallax, zooming and large movement. Respect their system setting:
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}
A blanket rule like this is a safe starting point; a better design swaps movement for a gentle fade rather than removing feedback entirely.
Worked example: a broken landing page
A landing page has: no lang; a hero image with no alt; light grey #aaa text on white in a notice; an email input with only a placeholder; a "Get started" <div> with a click handler; an <h1> followed directly by <h4>.
The smallest correct fixes:
| Issue | WCAG | Fix |
|---|---|---|
| No page language | 3.1.1 | <html lang="en"> |
| Image with no alt | 1.1.1 | alt="..." describing it, or alt="" if decorative |
#aaa on white (2.3:1) | 1.4.3 | A darker token, such as #595959 (7:1) |
| Placeholder-only input | 3.3.2, 4.1.2 | <label for="email">Email address</label> |
| Div button | 2.1.1, 4.1.2 | <button type="button">Get started</button> |
| h1 then h4 | 1.3.1 | Change to <h2>, and resize with CSS if needed |
After fixing, verify each one the same way you found it: rescan, tab through, check the ratio in DevTools, and listen with a screen reader.
Writing the summary
Close an audit with a short summary for the team: what you tested (pages, tools, browsers, screen readers), what you fixed, what remains with severity, and a recommendation (for example, "add axe checks to CI so these do not return"). For formal audits, the W3C's WCAG-EM methodology and its free report tool describe how to sample pages and report conformance.
Common mistakes
- Rewriting a whole component when one attribute would do.
- Fixing the visible symptom (a darker colour on one element) instead of the token.
- Adding ARIA to a
<div>instead of swapping in the native element. - Not re-testing after a fix.
- Changing a heading level by restyling instead of changing the element.
Quick recap
- Audit in a fixed order: scan, basics, keyboard, names, colour, zoom, motion, screen reader.
- Prefer the smallest native-HTML fix; fix shared tokens and components.
- Contrast: 4.5:1 text, 3:1 large text and UI; check with DevTools.
- Respect
prefers-reduced-motion. - Verify every fix the way you found it.
Try it
Open the Do tab and fix five accessibility issues in a broken landing page.