Toegankelijke formulieren: praktische implementatie
Formulieren zijn dé plek waar WCAG in de praktijk vaak faalt: ontbrekende labels, onduidelijke foutmeldingen, slecht focusbeheer en custom controls zonder keyboard-ondersteuning zorgen voor uitsluiting. Developers en redacties bouwen snel interfaces, maar missen vaak de concrete stappen om ze daadwerkelijk toegankelijk te maken.
Wij lossen dat door duidelijke, testbare patronen aan te bieden: kant-en-klare HTML, ARIA-annotaties, JavaScript routines voor validatie en focus-management, plus concrete testinstructies. Gebruik onze code direct, check je pagina met onze WCAG checker, download de plugin of neem contact op via het contactformulier (vragen binnen 24 uur beantwoord).
Het probleem in de praktijk
Ontbrekende of verkeerde labels
Veel velden missen een <label> of gebruiken placeholder als label. Placeholders zijn geen vervanging: ze verdwijnen en zijn niet semantisch gekoppeld.
Onduidelijke foutmeldingen en geen focus
Fouten worden visueel aangegeven zonder ARIA of automatische focus op het eerste foutveld. Screenreader-gebruikers missen zo belangrijke informatie.
Custom controls zonder keyboard/ARIA
Dropdowns, toggles en datepickers zonder role/keyboard handling breken voor keyboard- en assistive-tech gebruikers.
Zo los je dit op in code
Basis-HTML: correcte labels, required en aria-describedby
<form id="signup-form" novalidate><div><label for="email">E-mailadres<span aria-hidden="true">*</span></label><input id="email" name="email" type="email" required aria-describedby="email-help email-error"><small id="email-help">We gebruiken je e-mail alleen voor updates.</small><div id="email-error" class="error" aria-live="polite"></div></div><div><label for="password">Wachtwoord<br/><small>Minimaal 8 tekens</small></label><input id="password" name="password" type="password" required aria-describedby="password-error"><div id="password-error" class="error" aria-live="polite"></div></div><button type="submit">Aanmelden</button></form>
Client-side validatie: set aria-invalid en focus naar eerste fout
document.getElementById('signup-form').addEventListener('submit', function(e){e.preventDefault();const form=this;const fields=[form.email,form.password];let firstInvalid=null;fields.forEach(field=>{field.removeAttribute('aria-invalid');const errorEl=document.getElementById(field.id+'-error');errorEl.textContent='';if(!field.checkValidity()){field.setAttribute('aria-invalid','true');errorEl.textContent=field.validationMessage;errorEl.classList.add('visible');if(!firstInvalid)firstInvalid=field}});if(firstInvalid){firstInvalid.focus();return;} // stuur formulier via fetch of form.submit()
Server-side foutafhandeling met focus en role=alert
<div id="server-errors" role="alert" aria-live="assertive"></div><!-- server response handler -->fetch('/api/signup',{method:'POST',body:new FormData(form)}).then(r=>r.json()).then(data=>{if(data.errors){const alert=document.getElementById('server-errors');alert.textContent='Er zijn problemen; zie de velden.';const first=document.querySelector('[aria-invalid="true"], .error.visible');if(first){first.focus()}}})
Toegankelijke custom dropdown (ARIA + keyboard)
<div class="dropdown" role="combobox" aria-haspopup="listbox" aria-owns="options" aria-expanded="false"><button id="trigger">Kies optie</button><ul id="options" role="listbox" tabindex="-1" hidden><li role="option" data-value="1">Optie 1</li><li role="option" data-value="2">Optie 2</li></ul></div><script>// open/close, arrow keys, Enter selectie, roep focus terug naar button na selectie</script>
Checklist voor developers
- Elke input heeft een expliciet <label for=”id”> of aria-label als een visueel label niet mogelijk is.
- Placeholders nooit als enige label gebruiken.
- Gebruik aria-describedby om help- en foutteksten te koppelen.
- Zet aria-invalid=”true” op ongeldig veld en vul het foutblok met tekst.
- Bij submit: focus naar eerste invalid veld automatisch zetten.
- Gebruik role=”alert” of aria-live voor servererrors; assertive voor kritische fouten.
- Custom controls: juiste roles (combobox, listbox, option, switch), tabindex en keyboard-handling.
- Test met alleen toetsenbord, schermlezer (NVDA/VoiceOver) en onze WCAG checker.
Tips voor designers en redacties
Gebruik duidelijke labels en visuele indicatoren
Zet required-tekens en helptekst visueel dichtbij het veld. Zorg dat contrastnormen voor tekst en foutboodschappen voldoen aan WCAG AA.
Schrijf duidelijke foutmeldingen
Gebruik korte, actiegerichte fouten: “Vul een geldig e-mailadres in” in plaats van “Fout”. Plaats instructies vóór het veld of als helptekst met aria-describedby.
Formulierflow en microcopy
Ontwerp formulieren in logische stappen. Gebruik fieldsets en legends voor groepen (bijv. adresgegevens) zodat assistive tech de context begrijpt.
Hoe test je dit?
Snelle handtests (3 minuten)
- Verwijder muis: navigeer het formulier met Tab/Shift+Tab. Kun je elk element bereiken en activeren?
- Trigger fouten: laat velden leeg en verstuur. Is het eerste foutveld gefocust en is foutmelding uitgesproken door screenreader?
- Check labels: klik op label, focust het corresponderende veld?
Screenreader-tests
Open NVDA (Windows) of VoiceOver (Mac). Navigeer naar formulier: hoort de gebruiker label, type hint en helptekst in de juiste volgorde? Bij foutmelding moet aria-live of role=alert de boodschap direct voorlezen.
Automatische checkers + onze tool
Draai onze WCAG checker voor snelle resultaten (labels, ARIA-fouten, contrast). Gebruik ook onze plugin in je browser voor inline feedback tijdens development. Test zowel client- als server-rendered foutmeldingen; onze tool detecteert missende aria-describedby en role=alert-issues.
Gebruikcases testen
Test edgecases: zoom 400%, hoge contrastmodus, talen met langere labels, toetsenbord-only selectie van custom controls en schermlezers op mobiele browsers.
Praktische code-snippets om direct te plakken
Focus-first-invalid functie
function focusFirstInvalid(form){const invalid=form.querySelector('[aria-invalid="true"], :invalid');if(!invalid)return;invalid.focus();const err=document.getElementById(invalid.id+'-error');if(err)err.scrollIntoView({block:'center'});}
ARIA-live helper
function announce(message, assertive=false){let el=document.getElementById('aria-announcer');if(!el){el=document.createElement('div');el.id='aria-announcer';el.setAttribute('aria-live',assertive?'assertive':'polite');el.style.position='absolute';el.style.left='-9999px';document.body.appendChild(el);}el.textContent='';setTimeout(()=>el.textContent=message,100);}
Voorbeeld CSS voor foutstijlen en focus
.error{color:#b00020;font-size:0.9rem}.error.visible{display:block}.visually-hidden{position:absolute!important;height:1px;width:1px;overflow:hidden;clip:rect(1px,1px,1px,1px);white-space:nowrap}
Aanvullende teststappen (praktisch)
- Voer onze WCAG checker uit en los alle items op met prioriteit ‘High’ eerst.
- Integreer de plugin in je CI/build om regressies te voorkomen.
- Laat één ontwikkelaar en één redacteur hetzelfde formulier testen en vergelijk bevindingen; vaak ontdekt redacties onduidelijke microcopy.
Wanneer contact opnemen?
Stuit je op onopgeloste ARIA-problemen, custom controls die niet werken met screenreaders of wil je een accessibility-review van je formulier? Gebruik ons contactformulier. Wij beantwoorden binnen 24 uur en bieden concrete fixes en codevoorstellen.
Laat je formulier nu controleren met onze WCAG checker en download de plugin voor directe feedback tijdens development.
Laatste praktische tip: kopieer en plak de focus-first-invalid functie en de aria-live helper in je project; roep announce(‘Er zijn fouten in het formulier’,true) aan bij servererrors en focusFirstInvalid(form) bij client-side validatie. Test daarna direct met onze WCAG checker of vraag hulp via het contactformulier.