Skip to content
51studio
Tutorials

WCAG without the panic: a practical accessibility checklist

By Mira Solway10 min read

WCAG sounds intimidating. It's a 100-page document with three conformance levels, four principles, thirteen guidelines, and 78 success criteria. Teams read the first page and bail.

You don't need to read the spec. For most marketing sites and web apps, AA-level conformance is a checklist of about twelve concrete things. Hit all twelve and you've covered the cases that actually matter for users, accessibility regulators, and people running screen readers.

This post is that checklist. It's not the whole spec. It's the working subset for shipping a site that's actually usable.

AA vs AAA: what to aim for

The three WCAG conformance levels:

  • A — the minimum. If you fail A, your site is broken for some users. Hit this.
  • AA — the practical target for most sites. Required by EU's EAA, the ADA in the US, and equivalents in most jurisdictions.
  • AAA — extra strict. Rarely the right target; some AAA criteria conflict with mainstream design practices.

AA is the right target. Build for AA, fix anything you discover beyond that. Don't chase AAA unless you have a specific reason (government contracts, certain healthcare contexts).

The twelve-item checklist

These are the things we check on every project before launch. The order is roughly by frequency-of-failure.

1. Colour contrast

Body text needs 4.5:1 contrast against its background. Large text (18pt+) needs 3:1. Interactive elements (buttons, focus rings) need 3:1.

The trap: brand colours that look great on a mockup often fail. Pale grey body text on white is everywhere. So is white text on pastel buttons.

Tools: WebAIM Contrast Checker for one-off colours. Stark plugin in Figma. axe DevTools in browser for the rendered site.

2. Keyboard navigation

Every interactive element must be reachable and operable by keyboard. Tab moves between elements, Enter or Space activates them, Escape closes modals.

The traps:

  • Custom dropdowns built with <div> and click handlers. No keyboard support unless you add it.
  • Modals that don't trap focus. The user tabs out of the modal into the page behind it.
  • Skip-to-content links that are missing or hidden so you can't focus them.
  • Buttons made of <a> tags without role="button" and keyboard handlers.

Fix: use real semantic elements (<button>, <a>, <select>) where possible. When you have to use custom widgets, follow the ARIA Authoring Practices Guide patterns. Test by unplugging your mouse for an hour.

3. Focus visibility

When an element has keyboard focus, there must be a visible focus indicator. Browser default focus rings are ugly but functional. Many teams hide them with outline: none and forget to add a replacement.

Rule: never remove the focus outline without replacing it with something at least as visible. A custom focus ring is fine; no focus ring is not.

4. Alt text on images

Every image needs alt text. The right alt text depends on the image:

  • Informative images (photos with content, illustrations that mean something): describe what's there. "Two engineers reviewing a wireframe on a whiteboard."
  • Decorative images (background patterns, ornaments, redundant visuals next to text that says the same thing): empty alt. alt="". Not missing alt — explicitly empty.
  • Functional images (icons that act as buttons): describe the function, not the image. A magnifying-glass icon button should have alt="Search", not alt="Magnifying glass".

The most common mistake: using the file name as alt. alt="IMG_2934.jpg" is worse than no alt.

5. Form labels and errors

Every form input needs a visible, programmatically associated label. Placeholder text is not a label — when the user types, the placeholder disappears, and they've lost context.

html
<!-- Wrong -->
<input type="email" placeholder="Email">

<!-- Right -->
<label for="email">Email</label>
<input type="email" id="email" placeholder="name@company.com">

When validation fails, the error message must be associated with the field. aria-describedby on the input pointing to the error message's ID. Screen reader users hear the error when they focus the field.

6. Heading hierarchy

Pages have one <h1>, then <h2> for sections, <h3> for sub-sections. Don't skip levels (no <h1> followed directly by <h3>).

Screen reader users navigate by headings. A page with a flat heading structure is a wall of text to them. A page with a nested, semantic structure is a navigable document.

The trap: using headings for visual styling instead of structure. If you want big text, use CSS. If you want a heading, use <h2> and style it.

Links should make sense out of context. Screen readers can list all the links on a page; if half of them say "Click here" or "Learn more," the list is useless.

Bad: "Read more about our services [here]." Good: "Read [more about our services]."

Same words, different anchor. The link text is "more about our services," which means something on its own.

8. Touch target size

On mobile, interactive elements need to be at least 44×44 CSS pixels. Smaller and people with imprecise motor control can't hit them.

The trap: tightly packed nav links, social icons in the footer, dense form inputs. Each individually small. Cumulatively, the site is hard to use on a phone.

Fix: add padding, even when the visible element is small. The target area extends beyond the visible pixels.

9. Motion and animation

WCAG requires respecting prefers-reduced-motion. Users who get motion sickness, vestibular disorders, or just hate parallax effects set this preference at the OS level. Your site should honour it.

css
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

This is a hammer. A more nuanced approach: keep micro-interactions (fade-in, slight scale), drop heavy effects (parallax, large slides, autoplay video).

10. Document language

Every page needs <html lang="en"> (or appropriate locale). Screen readers use this to pick the right voice and pronunciation rules. Without it, English content might be read in a Polish accent.

For multi-language sites, change lang per page based on the actual language. Embedded snippets in another language can use <span lang="...">.

A link at the top of the page, usually hidden until focused, that jumps to the main content. Keyboard users press Tab once and can skip the navigation.

html
<a href="#main" class="skip-to-content">Skip to content</a>
...
<main id="main">...</main>

The class should hide the link visually but make it visible when focused. Don't use display: none; that removes it from the tab order.

12. ARIA when (and only when) needed

ARIA attributes (aria-label, aria-describedby, aria-live, etc.) add semantic information for assistive tech. They're powerful and overused.

Rule: prefer native HTML. Use <button> instead of <div role="button">. Use <nav> instead of <div role="navigation">. ARIA is for things HTML can't express (custom widgets, live regions, async loading states).

The most common useful ARIA on a marketing site:

  • aria-current="page" on the active navigation link
  • aria-live="polite" on form-submission status messages
  • aria-expanded on toggle buttons
  • aria-label on icon-only buttons

That's most of what you'll use.

The tooling

Automated tools catch maybe 30% of accessibility issues. They're necessary but not sufficient. The tools we use:

  • axe DevTools browser extension. Run it on every page. Find the easy wins.
  • Lighthouse accessibility audit. Runs the same engine. Useful for CI.
  • WAVE browser extension. Slightly different rule set than axe; sometimes catches different things.
  • Pa11y for CI integration. Fails the build if accessibility regresses.

What the automated tools miss:

  • Whether alt text is meaningful (they detect missing alt, not bad alt)
  • Whether keyboard navigation actually works
  • Whether the reading order makes sense
  • Whether content makes sense without colour (e.g., "click the green button")
  • Whether interactions are operable without a mouse

For those, you need manual testing.

The parts you can't automate

A real accessibility pass includes:

  • Keyboard-only test. Unplug the mouse. Use the site for fifteen minutes. Anything you can't do is a bug.
  • Screen reader test. Mac users have VoiceOver built in (Cmd+F5). Windows has NVDA (free). Use the site with the screen reader for ten minutes. Anything unclear is a bug.
  • Zoom test. Browser to 200% zoom. The layout should still work. No horizontal scrolling.
  • Reduced-motion test. Toggle prefers-reduced-motion in DevTools. Animations should reduce or stop.
  • Forced-colours test. Toggle Windows high-contrast mode (Mac equivalent: invert colours). Layout should survive.

Each takes 10-15 minutes. None require special skills. Half the accessibility bugs we find come out of these manual passes.

A worked example

We audited a marketing site last month. Automated tools flagged 12 issues. The manual pass found 18 more. The split:

  • Automated found: low contrast, missing alt, missing labels, missing lang attribute. Mechanical things.
  • Manual found: focus traps in modals, keyboard navigation broken on a custom carousel, screen reader reading the testimonial section before the hero (reading-order bug invisible to automated tools), three icon-only buttons with no label, a "click the green icon" instruction that fails for colour-blind users.

The mechanical fixes took two days. The manual-found fixes took five days. The site went from "almost AA" to "actually AA." Total time: a week.

A checklist before launch

Print this:

  • All text contrast meets 4.5:1 (3:1 for large text).
  • Every interactive element is reachable by keyboard.
  • Focus indicators are visible on every interactive element.
  • Every image has appropriate alt text (or alt="" for decorative).
  • Every form field has a visible, associated label.
  • Heading hierarchy is semantic (no skipped levels).
  • Links make sense out of context.
  • Touch targets are at least 44×44px.
  • prefers-reduced-motion is respected.
  • <html lang="..."> is set on every page.
  • Skip-to-content link exists and works.
  • ARIA is used only where native HTML can't carry the meaning.
  • Keyboard-only test passes.
  • Screen reader test passes.
  • 200% zoom test passes.

Fifteen items. None of them is hard. Most of them are checked easily. WCAG AA is not a research project; it's a checklist.

If you want a site built with accessibility from the start, see how we work on redesign and support. Accessibility is in from the start, not bolted on at the end.

Related articles