Skip to content
SOSEI
8 min readAccessibilityWCAGCompliance

WCAG 2.1 AA: The Accessibility Standard Every Modern Website Must Meet

The European Accessibility Act enforces WCAG 2.1 AA across the EU. Below is the practical checklist — colour contrast, keyboard navigation, semantic HTML, ARIA — that turns the legal text into something a small team can actually ship.

On 28 June 2025 the European Accessibility Act became enforceable across the EU, mandating WCAG 2.1 AA compliance for almost every consumer-facing digital service. A year in, the regulator and the small private-sector enforcement industry that has sprung up around it have made one thing clear: ignorance is not a defence, and retroactive fixes are far more expensive than building correctly from the start.

WCAG 2.1 AA reads, on first encounter, like a wall of acronyms. The reality is more practical: it’s a finite checklist of about 50 success criteria, of which perhaps 15 are where most real-world sites fail. The rest are either trivial or only apply to specialised content (video captioning, audio descriptions). The list below is the one SOSEI enforces at the renderer level on every site it generates.

PerceivableContrast 4.5:1Alt textResize 200%No info via colour onlyOperableKeyboard navigableSkip linksFocus visibleNo keyboard trapsUnderstandableLanguage declaredForm labelsError messagesConsistent navRobustValid HTMLARIA only if neededStatus messagesParses cleanly
The four WCAG principles — Perceivable, Operable, Understandable, Robust — and where most legacy sites lose points.

The fifteen criteria where most sites actually fail

1. Insufficient colour contrast (1.4.3)

Body text needs a contrast ratio of 4.5:1 against its background. Large text (18 pt or 14 pt bold) needs 3:1. UI elements like buttons and form-field borders also need 3:1 against adjacent colour. The single most common violation is light-grey caption text on white — a ratio of around 2.1:1 that looks fine to the designer with 20/20 vision and is unreadable to about a third of older or visually impaired visitors.

2. Missing alt text on meaningful images (1.1.1)

Every <img> needs an alt attribute. Meaningful images get descriptive alt text; purely decorative ones get alt="" (empty, not missing) so screen readers skip them. Logos get the company name. Product photos get a one-sentence description.

3. Keyboard navigability (2.1.1)

Every interactive element must be reachable and activatable using the Tab key alone. The most common culprit is custom-coded dropdown menus or modal dialogs that respond to mouse clicks but ignore Enter/Space. Test it yourself: tab through your homepage. If you can’t reach the primary CTA, neither can a screen-reader user.

4. No visible focus indicator (2.4.7)

When a tabbable element is focused, the user must be able to see which one it is. Modern CSS reset libraries often remove the browser default outline without replacing it. Restore it with a visible :focus-visiblering — 2 px of solid colour with sufficient contrast against the surface.

5. Skip-to-content link (2.4.1)

A keyboard or screen-reader user shouldn’t have to tab through 20 navigation items to reach the page content. A hidden <a href="#main">Skip to content</a> link as the first focusable element solves this; it appears visually only when focused.

6. Form fields without labels (1.3.1, 3.3.2)

Every input, textarea, and select needs a programmatically associated label — either a <label> element with matching for attribute, or aria-label. Placeholder text is not a label; it disappears the moment the user starts typing.

7. Language not declared (3.1.1)

Every page’s <html> tag needs a lang attribute (lang="en", lang="et", etc.). Without it, screen readers guess at pronunciation rules — turning Estonian into something like badly-spoken English.

8. Error messages not announced (3.3.1)

When form validation fails, the error must be visually identified, textually associated with the offending field via aria-describedby, and announced to assistive tech via an aria-live region or moved focus. Inline red text with no programmatic association is invisible to a screen reader.

9. Heading order broken (1.3.1)

Headings establish the document outline. They should descend without skipping levels: an h1 at the top, then sequential h2s for sections, then h3s nested under those. A page that jumps from h1 to h4 because the designer wanted smaller-looking type breaks screen-reader navigation.

10. Information conveyed by colour alone (1.4.1)

“Required fields are in red” fails for the ~8% of men and ~0.5% of women who are red-green colourblind. Use a second signal: an asterisk, the word “required,” an icon.

11. Reflow at 320 px (1.4.10)

At a viewport width of 320 CSS pixels, all content must remain readable and operable without horizontal scrolling. Side-scrolling tables, wide hero images, and floating chat widgets that overlay content all fail this. See Mobile-First Isn’t Optional for the composition side of the same problem.

12. Non-text contrast (1.4.11)

Button borders, input field outlines, and graphical icons need 3:1 contrast against their surrounding colour. Pale grey buttons on white — the “ghost button” aesthetic of 2016 — almost always fail this.

13. Status messages without aria-live (4.1.3)

“Your message has been sent” toasts need to be in an aria-live="polite" region (or have role="status"). Without that, the message appears visually but is silent to a screen reader.

14. Touch targets too small (2.5.5)

Targets must be at least 44 × 44 CSS pixels. Three text links sat next to each other with a 4 px gap fail this on mobile, even if each individual word is large enough.

15. Autoplay media without controls (1.4.2)

Anything that plays audio for more than 3 seconds automatically must have a user-accessible way to pause or stop it. The 2018 era of autoplaying video heroes with background music violates this instantly.

AAA · 19.6:1Black on white — body text gold standardAA · 7.4:1Dark grey on white — passes 4.5:1Borderline · 2.9:1Light grey on white — fails body textDecorative · 1.4:1 — invisible
Contrast at a glance: AAA (7:1), AA (4.5:1), and the failure zone below 3:1.

Why ARIA is usually the wrong answer

The first rule of ARIA — published by the WAI — is don’t use ARIA. A <button> element is keyboard-focusable, click-activatable, and announced as a button by every screen reader, for free. A <div role="button" tabindex="0"> with a custom keydown handler is none of those by default and gets all of them wrong about half the time.

Semantic HTML solves 90% of accessibility for free. Reach for ARIA only when no semantic element fits the job — tab panels, complex disclosure widgets, custom comboboxes.

How SOSEI enforces this on every generated site

Compliance is built into the renderer, not bolted on as a final audit step. Concretely:

  • The token compiler enforces AAA (7:1) contrast on body text and AA (4.5:1) on muted text. Tokens that would violate are auto-corrected at the “normalize” step.
  • Every image goes through the renderer’s imgTag helper, which requires alt text and explicit dimensions or throws.
  • Buttons are always real <button> elements, with a visible :focus-visible ring.
  • A skip-to-content link is added to every page. lang is set from the source-site language.
  • The site audit module re-runs WCAG checks after generation and flags any regressions in the parity report.

WCAG 2.1 AA is no longer a nice extra — it’s a legal baseline and a measurable lift in conversion (accessible forms complete faster, accessible navigation reaches more users). To see how your existing site scores, run the free analyzer — accessibility is one of seven dimensions in the 40-point audit.

Stop losing customers to a 2018 website.

Every day on outdated tech is leads walking past your front door. Get the free 40-point audit — see exactly what's broken across SEO, AI-discoverability, WCAG, GDPR, mobile, performance, and design. No signup. Results in seconds.

See your site's score