Ga naar inhoud
·3 min

WCAG toegankelijkheid: van vinkjeslijst naar gewoonte

Hoe je WCAG 2.1 AA niet als bureaucratie behandelt maar als kwaliteitsmaatstaf. Praktische patronen die ik gebruik in elk project.

ToegankelijkheidWCAGFrontendBest Practices

Toegankelijkheid heeft een imagoprobleem. Het wordt gezien als extra werk, een set regels die je na het bouwen moet afvinken, iets voor grote overheidsprojecten.

Na jaren van bouwen aan platformen voor miljoenen gebruikers — en het bouwen van AllyScan, een tool specifiek voor toegankelijkheidstesting — ben ik tot een andere conclusie gekomen: WCAG-compliance is gewoon goede code schrijven.

0 op 6
Nederlanders met functiebeperking
0+
WCAG 2.1 succescriteria
0%
Issues door automatisering vindbaar
0 extra
Kosten als je vroeg begint
Toegankelijkheid in cijfers: het raakt meer mensen dan je denkt

Waarom het ertoe doet

In Nederland heeft ongeveer 1 op de 6 mensen een functiebeperking die invloed heeft op hoe ze het web gebruiken. Visuele beperkingen, motorische beperkingen, dyslexie, epilepsie — het spectrum is breed.

Maar ook zonder beperking profiteer je van toegankelijke code:

  • Betere SEO: Semantische HTML en beschrijvende alt-teksten helpen zoekmachines
  • Verbeterde keyboard navigatie: Prettig voor power users, noodzakelijk voor anderen
  • Robustere code: Toegankelijke componenten zijn doorgaans beter doordacht
Ongeveer 1 op de 6 Nederlanders heeft een functiebeperking die invloed heeft op webgebruik

Wist je dat?

Toegankelijke code is betere code. Semantische HTML verbetert SEO, keyboard navigatie helpt power users, en robuuste componenten zijn beter onderhoudbaar.

🔍

1. Audit uitvoeren

Scan je site met axe DevTools of Lighthouse. Identificeer de grootste problemen.

🔧

2. Quick wins fixen

Alt-teksten, kleurcontrast, focus states en semantische HTML. Vaak 60% van de issues.

⌨️

3. Keyboard test

Navigeer je hele site met alleen het toetsenbord. Tab, Enter, Space, Escape.

🤖

4. Automatiseren

Voeg jest-axe en AllyScan toe aan je CI/CD pipeline. Maak het onmogelijk om regressies te mergen.

Het 4-stappen audit proces dat ik bij elk project volg

De patronen die ik overal gebruik

1. Semantische HTML als fundament

Voor accessibility geldt: gebruik het juiste element voor de juiste taak. Een <button> voor acties, een <a> voor navigatie, <nav> voor navigatieblokken.

// ❌ Niet dit
<div onClick={handleSubmit} className="btn">
  Versturen
</div>
 
// ✅ Maar dit
<button type="submit" onClick={handleSubmit}>
  Versturen
</button>

Het verschil: de button is automatisch focussable, reageert op Enter/Space, en schermlezer kondigt hem aan als button.

Ontoegankelijk component

  • <div onClick={...}> als button
  • Geen focus state zichtbaar
  • Kleurcontrast ratio 2.5:1
  • Geen ARIA labels
  • Niet bereikbaar met keyboard
VS

Toegankelijk component

  • <button> met semantische HTML
  • Duidelijke focus ring met outline
  • Kleurcontrast ratio 7:1 (AAA)
  • aria-label en aria-pressed
  • Tab, Enter en Space support
Het verschil: semantische HTML en goede focus management maken een component toegankelijk

2. Focus management

Modale dialogen, drawers en dynamische content vereisen bewust focus management:

export function Modal({ isOpen, onClose, children }: ModalProps) {
  const firstFocusableRef = useRef<HTMLButtonElement>(null);
 
  useEffect(() => {
    if (isOpen) {
      // Focus het eerste interactieve element bij openen
      firstFocusableRef.current?.focus();
    }
  }, [isOpen]);
 
  return isOpen ? (
    <div
      role="dialog"
      aria-modal="true"
      aria-labelledby="modal-title"
      // Voorkom focus buiten de modal
      onKeyDown={(e) => e.key === 'Escape' && onClose()}
    >
      <button ref={firstFocusableRef} onClick={onClose} aria-label="Sluit modal">
        ×
      </button>
      <h2 id="modal-title">{title}</h2>
      {children}
    </div>
  ) : null;
}

3. Kleurcontrast automatisch checken

Handmatig kleurcontrast controleren is tijdrovend en foutgevoelig. Ik gebruik een combinatie van:

  • Storybook met @storybook/addon-a11y voor visuele controle per component
  • axe-core in Jest tests voor geautomatiseerde checks
  • AllyScan voor productiesites (mijn eigen tool)
// Toegankelijkheidstest in Jest
import { axe, toHaveNoViolations } from 'jest-axe';
expect.extend(toHaveNoViolations);
 
it('Button has no accessibility violations', async () => {
  const { container } = render(<Button>Versturen</Button>);
  const results = await axe(container);
  expect(results).toHaveNoViolations();
});

4. Alt-teksten die betekenis toevoegen

// ❌ Nutteloos
<img src="leroy.jpg" alt="afbeelding" />
 
// ❌ Te beschrijvend
<img src="leroy.jpg" alt="Een foto van een man met bruin haar die naar de camera kijkt" />
 
// ✅ Context-gedreven
<img src="leroy.jpg" alt="Leroy Steding, Senior Full-Stack Developer" />
 
// ✅ Decoratief? Dan leeg laten.
<img src="decorative-wave.svg" alt="" role="presentation" />

5. ARIA alleen als nodig

Een veelgemaakte fout is ARIA overal toevoegen. De eerste regel van ARIA gebruik: gebruik geen ARIA als je een native HTML element kunt gebruiken.

// ❌ Overbodig
<button aria-role="button">Klik hier</button>
 
// ✅ Nuttig: status melden aan schermlezer
<button aria-pressed={isActive} onClick={toggle}>
  {isActive ? 'Aan' : 'Uit'}
</button>

AllyScan: toegankelijkheid automatiseren

AllyScan in de CI/CD pipeline: ontoegankelijke code kan niet gemerged worden

Dit is precies waarom ik AllyScan heb gebouwd. Een CI/CD pipeline die na elke deployment automatisch je volledige site doorscant op WCAG 2.1 AA/AAA overtredingen, met een Chrome-extensie voor realtime feedback tijdens het ontwikkelen.

Het principe: maak het onmogelijk om ontoegankelijke code te mergen.

# .github/workflows/accessibility.yml
- name: Run AllyScan
  run: npx allyscan --url ${{ env.DEPLOY_URL }} --standard WCAG21AA
  env:
    ALLYSCAN_TOKEN: ${{ secrets.ALLYSCAN_TOKEN }}

Hoe je ermee start

  1. Installeer de axe DevTools browser extensie — gratis, geeft direct feedback
  2. Navigeer je site met alleen het toetsenbord — Tab, Shift+Tab, Enter, Space, pijltoetsen. Is alles bereikbaar?
  3. Zet een schermlezer aan — NVDA (Windows, gratis), VoiceOver (Mac/iOS, ingebouwd), TalkBack (Android)
  4. Voeg jest-axe toe aan je bestaande test suite

Toegankelijkheid hoeft niet perfect te zijn op dag één. Maar het moet wel structureel verbeteren. Begin klein, maak het onderdeel van je definition of done, en bouw het in je tooling.

Je gebruikers — alle gebruikers — verdienen het.

Blijf op de hoogte

Ontvang nieuwe artikelen direct in je inbox. Geen spam, alleen waardevolle content.

Plan een gesprek