Toegankelijke formulieren en foutmeldingen: praktisch toepassen
Formulieren falen in de praktijk vaak op twee fronten: onduidelijke labels / foutmeldingen en slechte ondersteuning voor schermlezers en toetsenbordgebruik. Dat leidt tot afgebroken conversies en uitsluiting van gebruikers.
Wij lossen dit op met concrete, testbare patterns: semantische HTML, duidelijke aria-relaties, een toegankelijke fout-samenvatting en eenvoudige JavaScript-hooks die je direct in je codebase kunt plakken. Test direct met onze WCAG checker of download de plugin — vragen? Gebruik het contactformulier, we reageren binnen 24 uur.
Het probleem in de praktijk
Veel voorkomende fouten bij formulieren:
- Labels ontbreken of zijn niet expliciet gekoppeld (for/id), waardoor schermlezers velden niet herkennen.
- Inline foutmeldingen zijn niet gekoppeld met aria-describedby of aria-invalid, dus schermlezers melden geen fout.
- Geen fout-samenvatting bovenaan, dus keyboard- of screenreader-gebruikers zien niet welke velden aandacht nodig hebben.
- Focus management ontbreekt: focus springt niet naar fout-samenvatting of eerste foutveld.
- Visuele foutstyling is niet gekoppeld aan aria-invalid of beschikbaarheid is alleen met kleur aangegeven (contrast/zonder icon of tekst).
Zo los je dit op in code
1) Gebruik semantische HTML en correcte labels
Altijd label met for + id, of een wrapper label
rondom het input-element.
<label for="email">E-mailadres</label><br><input id="email" name="email" type="email" required aria-required="true">
2) Verbeter foutmeldingen met aria-describedby en aria-invalid
Koppel fouttekst aan het input met aria-describedby
en zet aria-invalid="true"
wanneer er een fout is.
<input id="email" name="email" type="email" aria-describedby="email-error" aria-invalid="true"><br><span id="email-error" role="alert">Voer een geldig e-mailadres in</span>
3) Voeg een toegankelijke fout-samenvatting toe
Een fout-samenvatting bovenaan het formulier met links naar de velden helpt keyboard- en screenreader-gebruikers.
<div id="error-summary" tabindex="-1" aria-labelledby="error-summary-title" role="alert" aria-live="assertive"><h2 id="error-summary-title">Er zijn fouten in het formulier</h2><ul id="error-list"><li><a href="#email">E-mailadres: Ongeldig</a></li></ul></div>
4) Focus management: zet focus op de fout-samenvatting
Zodra validatie faalt, focus verplaatsen naar de fout-samenvatting zorgt dat gebruikers direct weten wat er mis is.
function focusErrorSummary(){const summary=document.getElementById('error-summary');if(summary){summary.focus();}}
5) Server-side validatie + client-side ARIA updates
Zorg dat server-side errors teruggegeven worden in JSON en dat je client-side ARIA-attributes instelt op basis van de response.
fetch('/api/submit',{method:'POST',body:formData}).then(r=>r.json()).then(data => {if(data.errors){applyErrors(data.errors);focusErrorSummary();}});
6) CSS: zichtbare focus- en foutstijl die niet alleen op kleur leunt
Voorbeeld CSS-patterns (gebruik duidelijke iconen, tekst en indicatoren):
.input-error{outline:2px solid #B00020;box-shadow:0 0 0 3px rgba(176,0,32,0.08);}input:focus{outline:3px solid #005FCC;} .visually-hidden{position:absolute!important;height:1px;width:1px;overflow:hidden;clip:rect(1px,1px,1px,1px);white-space:nowrap;border:0;padding:0;margin:-1px;}
7) Voorbeeld: volledig minimal formulier met toegankelijke foutafhandeling
<form id="signup"><div id="error-summary" tabindex="-1" role="alert" aria-live="assertive" class="visually-hidden"><h2>Er zijn fouten in het formulier</h2><ul id="error-list"></ul></div><label for="email">E-mailadres</label><input id="email" name="email" type="email" aria-describedby="email-error"><span id="email-error" class="visually-hidden" role="alert"></span><button type="submit">Verstuur</button></form><script>document.getElementById('signup').addEventListener('submit',function(e){e.preventDefault();const email=document.getElementById('email');const errors=[];document.getElementById('error-list').innerHTML='';email.removeAttribute('aria-invalid');document.getElementById('email-error').textContent='';document.getElementById('error-summary').classList.add('visually-hidden');if(!/^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$/.test(email.value)){errors.push({field:'email',message:'Voer een geldig e-mailadres in'});}if(errors.length){errors.forEach(err => {const li=document.createElement('li');const a=document.createElement('a');a.href='#'+err.field;a.textContent=err.field+': '+err.message;li.appendChild(a);document.getElementById('error-list').appendChild(li);const input=document.getElementById(err.field);input.setAttribute('aria-invalid','true');const desc=document.getElementById(err.field+'-error');desc.textContent=err.message;desc.classList.remove('visually-hidden');});const summary=document.getElementById('error-summary');summary.classList.remove('visually-hidden');summary.focus();}else{ // submit via fetch or normal submit } });</script>
Checklist voor developers
- Labels: voor elk input-element een expliciet
<label for="id">
of een wrapper-label. - Fouten: gebruik
aria-describedby
+role="alert"
voor inline fouten enaria-invalid="true"
op foutvelden. - Error summary: toon bovenaan een fout-samenvatting met anchors naar velden en zet focus erop.
- Keyboard: controleer tabvolgorde, focus-stijlen en dat links in de error-summary werken met Enter/Space.
- Server-side: stuur veldspecifieke foutcodes en vertaal die naar aria-updates client-side.
- Visueel: gebruik meer dan kleur (icon + tekst) en voldoende contrast voor foutindicatie.
- Automatisch testen: schrijf integratie-tests die fouten forceren en checken op aria-attributes en focus.
Tips voor designers en redacties
Formulierlabels en microcopy
Gebruik korte, duidelijke labels. Plaats hulptekst als aanvullende context met aria-describedby
. Vermijd placeholders als enige label — ze verdwijnen bij invoer.
Foutmeldingsstijl
Maak foutteksten kort, specifiek en oplossingsgericht: niet “Ongeldige input” maar “Voer een geldig e-mailadres in (voorbeeld@domein.nl)”. Voeg icons en kleur met voldoende contrast toe.
UX-flow
Zorg dat de fout-samenvatting direct zichtbaar is bij (her)submit, en dat gebruikers met één klik naar het foutveld kunnen springen. Denk in scenario’s: mobiel, toetsenbordgebruik, schermlezer.
Hoe test je dit?
Handmatige tests (snel en effectief)
- Navigeer met Tab door het formulier: focusvolgorde is logisch en focus-styles zichtbaar.
- Submit zonder verplichte velden: fout-samenvatting verschijnt en focus gaat naar de samenvatting.
- Klik link in fout-samenvatting: focus verplaatst naar het correcte veld.
- Controleer met schermlezer (NVDA/VoiceOver): foutberichten worden aangekondigd (aria-live / role=alert).
Screenreader quick-check
NVDA (Windows): Open NVDA & gebruik Tab en Enter; VoiceOver (macOS/iOS): VO+Space en rotor gebruiken. Verifieer dat inline fouten en de error summary voorgelezen worden.
Automatische tests
Integreer end-to-end tests (Cypress/Puppeteer) die:
- Submit foute input en assert op presence van
aria-invalid="true"
. - Assert dat
#error-summary
visible en focusable is. - Controleer links in error-list navigeren naar inputs.
Gebruik onze tools
Test je pagina direct met onze WCAG checker/validator en installeer de WCAGtool plugin voor snelle lokale scans. Vragen over implementatie? Stuur ons een bericht via het contactformulier — antwoord binnen 24 uur.
Wil je meteen actie? Kopieer bovenstaand formulier naar je staging site en draai de scanner — je ontvangt een overzicht met concrete verbeterpunten.