WCAG praktisch toepassen: direct inzetbare code en tests
Veel implementaties mislukken niet omdat teams de richtlijnen niet kennen, maar omdat ze te abstract zijn of niet praktisch genoeg uitgewerkt. Dit artikel pakt een veel voorkomend WCAG-onderwerp aan met duidelijke stappen, testbare code en checklists zodat developers, frontend engineers, UX/UI designers en redacteurs direct aan de slag kunnen.
Wij vertalen WCAG naar concrete patterns die je kunt copy-pasten, testen met onze WCAG checker/validator en automatiseren via onze plugin. Vragen? Gebruik ons contactformulier — we antwoorden binnen 24 uur.
Het probleem in de praktijk
Een regelmatig voorkomend probleem is onzichtbare of incorrecte focus, onvolledige ARIA-implementatie en onbruikbare interactieve componenten (modals, dropdowns, custom widgets). Resultaat: toetsenbordgebruikers en screenreaders kunnen niet navigeren of krijgen verkeerde informatie.
Oorzaken: gebrek aan consistente focusstyles, vergeten role/aria-attributes, niet goed beheer van focus bij modals en dynamische updates zonder aria-live. Wij lossen dit op met concrete codepatronen en teststappen.
Zo los je dit op in code
1) Toegankelijke, zichtbare focus-styling (CSS)
Probleem: browsers tonen soms nagenoeg onzichtbare focus. Oplossing: expliciete focusstijl die contrast houdt en geen layout-shifts veroorzaakt.
<!-- CSS: focus zichtbaar en consistent --><br>button, a, [tabindex] { outline: none; }<br>:focus { box-shadow: 0 0 0 3px rgba(10,132,255,.25); border-radius: 4px; }<br>:focus:not(:focus-visible) { box-shadow: none; }<br>
2) Skiplinks
Een simpele skiplink verbetert keyboard- en screenreader-navigatie aanzienlijk. Zorg dat de link bij focus zichtbaar wordt.
<!-- HTML --><br><a class="skip-link" href="#main">Sla naar inhoud</a><br><!-- CSS --><br>.skip-link { position: absolute; top:-40px; left:8px; background:#000; color:#fff; padding:8px; z-index:1000; }<br>.skip-link:focus { top:8px; }
3) Modals: focus trapping en aria-hidden
Belangrijk: verberg achtergrond voor AT, trap focus binnen modal en zet initial focus naar de eerste relevante interactive control.
<!-- Minimale accessible modal pattern --><br><div id="overlay" aria-hidden="true" style="display:none;"></div><br><div id="modal" role="dialog" aria-modal="true" aria-labelledby="modal-title" style="display:none;"><br> <h2 id="modal-title">Instellingen</h2><br> <button id="closeModal">Sluiten</button><br></div><br><!-- JavaScript: open/close + focus trap --><br>function openModal(){ document.getElementById('overlay').style.display='block'; document.getElementById('overlay').setAttribute('aria-hidden','false'); const modal=document.getElementById('modal'); modal.style.display='block'; modal.querySelector('button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])')?.focus(); document.body.setAttribute('aria-hidden','true'); trapFocus(modal);}<br>function closeModal(){ document.getElementById('overlay').style.display='none'; document.getElementById('overlay').setAttribute('aria-hidden','true'); const modal=document.getElementById('modal'); modal.style.display='none'; document.body.removeAttribute('aria-hidden'); if(window.previousFocus)window.previousFocus.focus();}<br>function trapFocus(modal){ const focusable='button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])'; const elements=[...modal.querySelectorAll(focusable)]; const first=elements[0]; const last=elements[elements.length-1]; modal.addEventListener('keydown',function(e){ if(e.key==='Tab'){ if(e.shiftKey&&document.activeElement===first){ e.preventDefault(); last.focus(); }else if(!e.shiftKey&&document.activeElement===last){ e.preventDefault(); first.focus(); }} });}
4) ARIA: correcte rollen en properties
Gebruik ARIA alleen wanneer native semantics niet volstaan. Voor custom widgets: role, aria-expanded, aria-controls en aria-describedby zijn essentieel.
<!-- Voorbeeld custom accordion --><br><button class="accordion-button" aria-expanded="false" aria-controls="panel-1" id="acc-1">Sectie 1</button><br><div id="panel-1" role="region" aria-labelledby="acc-1" hidden>Inhoud</div><br><!-- JS: toggle --><br>document.querySelectorAll('.accordion-button').forEach(btn=>{ btn.addEventListener('click',()=>{ const open=btn.getAttribute('aria-expanded')==='true'; btn.setAttribute('aria-expanded',!open); document.getElementById(btn.getAttribute('aria-controls')).hidden=open; }); });
5) Dynamische updates: aria-live
Use aria-live regions voor meldingen die niet per se focus moeten krijgen (bijv. formuliervalidatie inline).
<!-- aria-live voorbeeld --><br><div aria-live="polite" id="msg"></div><br>function showMessage(text){ const msg=document.getElementById('msg'); msg.textContent=''; setTimeout(()=>msg.textContent=text,50); }
Checklist voor developers
- Tabvolgorde logisch? Test via keyboard (Tab/Shift+Tab).
- Alle interactieve elementen focusbaar? (a, button, input of tabindex)
- Focusstijl zichtbaar en contrastvol voor text/background.
- ARIA alleen gebruiken wanneer nodig; roles en properties kloppen.
- Modals trap focus en gebruiken aria-modal/aria-hidden correct.
- Formuliervalidering geeft inline, programmatic focus en aria-invalid/aria-describedby.
- Contrast >= 4.5:1 voor tekst (controleer met onze WCAG checker/validator).
- Media heeft ondertitels/alternatieve tekst of transcripten.
- Afbeeldingen hebben alt-attribuut of role=”presentation” als decoratief.
Snel testscript (CLI-achtig)
Gebruik deze stappen voor een snelle handmatige QA:
1. Open pagina in browser. 2. Tab door alle interactieve elementen. 3. Controleer visuele focus. 4. Activeer modal/dynamic content: kan je eruit tabben? 5. Run wcagtool.nl/checker en download de plugin.
Tips voor designers en redacties
Ontwerpcomponenten met accessibility-first
Maak design tokens voor focus, spacing en kleurcontrast. Documenteer states (focus, hover, disabled) in Storybook met accessibility-addon en geef developers code-snippets.
Content-editing: alt-teksten en kopstructuur
Redacteurs: schrijf alt-teksten die functioneel zijn (niet “afbeelding1”). Gebruik consistente H1-H2-H3 hiërarchie. Voor complexe afbeeldingen: voeg lang-description of link naar transcript toe.
Microcopy en labels
Zorg voor duidelijke labels en aanvullende aria-describedby voor extra context (bijv. “Velden gemarkeerd met * zijn verplicht”). Voor formulieren:
<label for="email">E-mailadres</label><br><input id="email" name="email" type="email" aria-describedby="email-hint"><br><small id="email-hint">We sturen geen ongevraagde mailings.</small>
Hoe test je dit?
1) Handmatig: keyboard + screenreader
Stap-voor-stap handtest:
- Keyboard-only navigatie: Tab, Shift+Tab, Enter, Space, Arrow keys.
- Screenreader: test met NVDA/JAWS (Windows) en VoiceOver (Mac/iOS). Controleer leesvolgorde, button labels en ARIA.
- Formuliervalidatie: foutmeldingen moeten programmatically focusbaar zijn of in aria-live verschijnen.
2) Automatisch: gebruik onze WCAG checker/validator
Voer je URL direct in op wcagtool.nl/checker voor snelle scans op contrast, missing alt, headings en ARIA-problemen. Download onze plugin voor CI/CD-integratie en automatische PR-checks.
3) Visuele contrast en color blindness simulatie
Gebruik onze checker voor kleurcontrasten en test met color-blindness simulators in devtools. Minimaliseer reliance op kleur alleen — voeg iconen of tekstlabels toe.
4) Testcases die je direct kunt doorlopen
- Open pagina, verwijder muis en navigeer volledig met keyboard binnen 5 minuten.
- Open modal, sluit met Esc, focus terug op element dat modal opende.
- Gebruik schermlezer: alle belangrijke componenten moeten expliciet benoemd worden.
- Run wcagtool.nl/checker en los alle high-priority issues op.
Wil je een stap-voor-stap audit? Upload je URL in onze WCAG checker/validator of installeer onze plugin voor automatische scans. Vragen via het contactformulier — we antwoorden binnen 24 uur.
Laatste praktische tip
Gebruik dit kleine script om onzichtbare focusproblemen tijdelijk te detecteren en te loggen tijdens development. Kopieer naar browser console of voeg toe aan je dev-helper.
// Focus-debugger: markeert en logt focusable elementsdocument.addEventListener('keydown',function(e){if(e.key==='F2'){const els=[...document.querySelectorAll('a,button,input,select,textarea,[tabindex]')];els.forEach(el=>{el.style.outline='2px dashed rgba(255,0,0,.7)';});console.log('Focusables:',els);setTimeout(()=>els.forEach(el=>el.style.outline=''),5000);}});
Test je website direct met onze WCAG checker/validator op wcagtool.nl/checker, download de plugin voor je buildproces via wcagtool.nl/plugin en stel vragen via het contactformulier op wcagtool.nl/contact — altijd antwoord binnen 24 uur.