May 12, 2026 · Tommy Bordas

Web accessibility, the developer's practical guide (WCAG, RGAA, EAA)

accessibilitya11ywcagrgaaweb

Web accessibility is no longer optional: since June 28, 2025, the European Accessibility Act makes it mandatory for most private-sector digital services. Here's a practical guide for developers: the WCAG principles, the most common mistakes, and how to fix them with real code.

Why accessibility, and why now

Making a site accessible means letting a blind, low-vision, deaf, motor-impaired or cognitively impaired person use the service like everyone else. That's roughly 20% of the population, and beyond permanent disability, everyone benefits from an accessible site: keyboard navigation, readable contrast in bright sunlight, captions on the train.

The context changed in 2025. The European Accessibility Act (directive 2019/882) has applied since June 28, 2025 to many private-sector digital services: e-commerce, banking, transport, online services. In France, the RGAA (Référentiel Général d'Amélioration de l'Accessibilité) remains the official framework for the public sector and some companies. Both rest on the same technical foundation: the WCAG.

Takeaway: accessibility is no longer just a matter of ethics or image. It's a legal obligation, with a risk of penalty, and it also improves SEO and conversion. Better to handle it from day one.

WCAG: the 4 principles and the 3 levels

The Web Content Accessibility Guidelines (version 2.2, the most recent) rest on 4 principles, summed up by the acronym POUR: Perceivable, Operable, Understandable, Robust. Each criterion is graded across three conformance levels.

Level Requirement Legal target
A Bare minimum Not enough alone
AA Expected standard Yes (EAA, RGAA)
AAA Enhanced Optional, case by case

The level required by law is AA. That's the one that should guide your daily choices.

The 6 most common mistakes (and their fixes)

1. Non-semantic HTML (the do-everything div)

The most widespread mistake: a <div onclick> instead of a real button. The screen reader doesn't announce it as clickable, and it isn't keyboard-focusable. The fix is free: use the right element.

<!-- Avoid: invisible to keyboard and screen reader -->
<div class="btn" onclick="submit()">Send</div>

<!-- Correct: focusable, keyboard-activatable, announced as a button -->
<button type="submit">Send</button>

2. Images without a text alternative

Every meaningful image needs an alt attribute describing its content. A purely decorative image takes an empty alt so the screen reader skips it.

<img src="sales-chart.png"
     alt="Sales up 30% between January and March">

<!-- Decorative image: empty alt, never a missing alt -->
<img src="divider.svg" alt="">

3. Insufficient contrast

Light grey on a white background looks nice in the mockup and is unreadable in real life. Level AA requires a contrast ratio of at least 4.5:1 for normal text, and 3:1 for large text (from 24px, or 18.5px bold).

Text type AA minimum ratio
Normal text 4.5:1
Large text 3:1
Components and icons 3:1

4. Broken keyboard navigation

A user who can't use a mouse must be able to do everything with the Tab key. Two rules: never remove the visible focus, and provide a skip link to jump straight to the content.

/* NEVER remove the outline without replacing it */
:focus-visible {
  outline: 2px solid var(--tb-accent);
  outline-offset: 2px;
}
<!-- Skip link, the first focusable element on the page -->
<a href="#content" class="skip-link">Skip to content</a>

5. Forms without linked labels

A field without an associated <label> is a silent input for the screen reader. The link is made with for and id.

<label for="email">Email address</label>
<input id="email" type="email" name="email"
       autocomplete="email" required>

6. Misused ARIA (worse than no ARIA)

ARIA exists to express what native HTML can't, not to replace it. ARIA's first rule: if a native HTML element exists, use it. A wrong role breaks more than it fixes. Reserve ARIA for rich components (tabs, modals, menus) and dynamic content.

<!-- Announce a dynamic message without moving focus -->
<div aria-live="polite" id="status"></div>

How to test your accessibility

No automated tool covers everything. The right approach combines automated and manual checks.

  • By keyboard: unplug the mouse and go through the whole site with Tab. If you can, you've already solved half the problems.
  • With a screen reader: test with VoiceOver (macOS/iOS), NVDA (Windows) or TalkBack (Android).
  • Automated: axe DevTools, Lighthouse or Pa11y catch mechanical errors (contrast, missing alt, labels).
  • Contrast: Chrome DevTools' contrast panel or a dedicated tool.

Takeaway: automated tools catch roughly 30% to 40% of issues. The rest surfaces with the keyboard and the screen reader. A serious audit always does both.

The baseline accessibility checklist

  • Semantic HTML (buttons, links, hierarchical h1-h6 headings)
  • Relevant alt on every meaningful image
  • AA contrast verified (4.5:1 for normal text)
  • Full keyboard navigation, visible focus preserved
  • Skip link to the main content
  • Linked labels on every form field
  • Error messages and dynamic content announced (aria-live)
  • Keyboard and screen-reader testing before going live

Going further

Accessibility is part of a site's overall quality, just like performance. See also my audit method: Web performance audit, my 5-step method.

Does your site need to comply with the European Accessibility Act? Let's talk.