Beste browserextensies voor WCAG-testen (Chrome, Firefox)

Toegankelijke formulieren: labels, foutmeldingen en focus — wcagtool.nl

Toegankelijke formulieren: labels, foutmeldingen en focus

Formulieren falen vaak in de praktijk: onduidelijke of ontbrekende labels, foutmeldingen die niet gelezen worden door schermlezers en focus die niet naar het eerste foutveld springt. Dat zorgt voor frictie voor mensen met een beperking en voor hogere drop-off rates.

Wij helpen je stap-voor-stap met concrete code, testbare patronen en checklists zodat jouw formulieren voldoen aan WCAG en direct inzetbaar zijn. Test je site na elk hoofdstuk met onze WCAG checker/validator, download onze plugin voor IDE-integratie via plugin downloaden en stel vragen via het contactformulier — we reageren binnen 24 uur.

Het probleem in de praktijk

Veelvoorkomende fouten die we in audits zien:

  • Labels ontbreken of zijn visueel maar niet semantisch gekoppeld (placeholder used as label).
  • Foutmeldingen zijn visueel aanwezig maar niet in een role/aria-live region, waardoor schermlezers ze missen.
  • Focus blijft op de verzendknop na submit, in plaats van naar het eerste ongeldige veld te springen.
  • Inline validatie is inconsistent: geen aria-invalid, geen aria-describedby of id-ref naar de foutboodschap.

Deze problemen zijn eenvoudig te verhelpen met consistente HTML-structuur, ARIA-attributen en één kleine JavaScript-functie die de focus goed zet. Hieronder concrete implementatie.

Zo los je dit op in code

1. Semantische labels die altijd aanwezig zijn

Gebruik altijd <label for=””> gekoppeld aan <input id=””>. Gebruik placeholders alleen als aanvulling, nooit als vervanging.

<label for="email">E-mailadres</label><input id="email" name="email" type="email" required aria-required="true" />

2. Foutmeldingen: aria-describedby + role=”alert”

Maak per veld een foutboodschap-element met een id en verwijs ernaar met aria-describedby. Geef dynamische foutmeldingen role=”alert” of aria-live=”assertive” zodat schermlezers ze direct aankondigen.

<input id="email" name="email" type="email" aria-describedby="email-error" aria-invalid="false" /><div id="email-error" class="error" role="alert" aria-live="assertive"></div>

3. Focus-management bij submit

Zet focus op het eerste ongeldige veld en zet aria-invalid op true. Hieronder een compacte, testbare JS-functie.

function focusFirstInvalid(form){const invalid = form.querySelector('[aria-invalid="true"],:invalid');if(invalid){invalid.focus();invalid.scrollIntoView({behavior:"smooth",block:"center"});}return !!invalid;}document.addEventListener('submit',function(e){const form=e.target;if(form.matches('form')){e.preventDefault();const elems=[...form.elements];let firstInvalid=null;elems.forEach(el=>{if(!el.checkValidity()){el.setAttribute('aria-invalid','true');const msg=el.validationMessage||'Vul dit veld correct in';const errId=el.getAttribute('aria-describedby')||el.id+'-error';let err=document.getElementById(errId);if(!err){err=document.createElement('div');err.id=errId;err.className='error';err.setAttribute('role','alert');err.setAttribute('aria-live','assertive');el.insertAdjacentElement('afterend',err);}err.textContent=msg;if(!firstInvalid)firstInvalid=el;}else{el.removeAttribute('aria-invalid');const desc=el.getAttribute('aria-describedby');if(desc){const err=document.getElementById(desc);if(err)err.textContent='';}}});if(firstInvalid){firstInvalid.focus();firstInvalid.scrollIntoView({behavior:'smooth',block:'center'});}else{form.submit();}}});

4. Voorbeeld: volledig formulier

<form id="signup" novalidate><label for="name">Naam</label><input id="name" name="name" type="text" required aria-required="true" aria-describedby="name-error" /><div id="name-error" class="error" role="alert" aria-live="polite"></div><label for="email">E-mail</label><input id="email" name="email" type="email" required aria-required="true" aria-describedby="email-error" /><div id="email-error" class="error" role="alert" aria-live="assertive"></div><button type="submit">Versturen</button></form>

5. CSS: duidelijke focus en zichtbare fouten

Gebruik zichtbare focusstijlen en contrastrijke foutkleuren. Vermijd alleen kleur als enige betekenis.

.error{color:#b00020;font-size:.9rem;margin-top:.25rem}.error:empty{display:none}input:focus{outline:3px solid #005fcc;outline-offset:2px}input[aria-invalid="true"]{border:2px solid #b00020}

Checklist voor developers

  • Elke input heeft een semantisch <label for=”id”> gekoppeld.
  • Verwijzingen: aria-describedby wijst naar foutboodschap-id.
  • Dynamische foutboodschappen hebben role=”alert” of aria-live=”assertive”.
  • Bij validatie: zet aria-invalid=”true” op ongeldige velden.
  • Bij submit: script focust eerste ongeldige veld en rolt het in beeld.
  • Focusstijlen zijn duidelijk en niet verwijderd met outline: none.
  • Gebruik native HTML-validatie waar mogelijk en breid uit met JS voor custom checks.
  • Run na implementatie direct onze WCAG checker/validator en installeer onze IDE-plugin: plugin downloaden.

Tips voor designers en redacties

Labels & placeholders

Ontwerp altijd ruimte voor permanente labels. Placeholders mogen ondersteunend zijn maar niet de enige instructie.

Kleur en contrast

Gebruik naast kleur ook iconen of tekst om status aan te geven (bijv. fouticoon + “Veld verplicht”). Test contrast voor focus- en foutstaten met onze checker.

Redactie: helptekst en validatieregels

Schrijf korte, duidelijke foutmeldingen en helpteksten. Voorbeeld: “Gebruik een geldig e-mailadres zoals naam@voorbeeld.nl” in plaats van “ongeldig”. Zet deze tekst in het CMS als aparte veld zodat de frontend automatisch aria-describedby kan invullen.

Hoe test je dit?

Automatische checks

Draai onze WCAG checker/validator op je pagina en kijk specifiek naar: ontbrekende labels, aria-describedby referenties en role=”alert” elementen. Installeer onze plugin voor CI-integratie zodat elke build automatisch wordt gescand.

Handmatige tests – keyboard only

  1. Navigeer volledig met Tab en Shift+Tab; alle interactieve elementen moeten bereikbaar zijn.
  2. Vul formulier gedeeltelijk en druk Enter; de focus moet naar het eerste foutveld springen.
  3. Controleer of foutboodschappen voor het scherm in zichtbare context verschijnen en dat focus niet vast blijft zitten.

Screenreader-test

  1. Open NVDA (Windows) of VoiceOver (macOS) en navigeer naar formulier.
  2. Voer onjuiste invoer in en verstuur; luister of foutberichten worden voorgelezen (role=”alert” / aria-live).
  3. Controleer dat aria-describedby wordt aangekondigd bij focus op het veld.

Acceptance tests voor CI

Schrijf e2e-tests (Cypress/Puppeteer) die:

  1. Submitten met lege verplichte velden en asserten dat focus op het juiste element staat.
  2. Controleer dat aria-invalid aanwezig is na invalidatie.
  3. Valideer dat foutboodschap-elementen textContent bevatten en role=”alert”.

Voorbeeld Cypress-assertie:

cy.get('form#signup').submit();cy.get('#name').should('have.attr','aria-invalid','true');cy.focused().should('have.id','name');cy.get('#name-error').should('contain','Vul dit veld');

Test je implementatie direct met onze WCAG checker/validator en activeer onze plugin via plugin downloaden voor integratie in je workflow. Bij vragen: gebruik het contactformulier — antwoord binnen 24 uur.

Laatste praktische tip: voeg deze kleine helper toe aan je globale scripts om consistentie te garanderen — kopieer en plak in je project:

export function applyFormAccessibility(form){form.setAttribute('novalidate','true');form.querySelectorAll('input,textarea,select').forEach(el=>{if(!el.id){el.id='fld-'+Math.random().toString(36).substr(2,9);}if(!document.querySelector('label[for=\"'+el.id+'\"]')){el.setAttribute('aria-label',el.placeholder||el.name||'veld');}const desc=el.getAttribute('aria-describedby');if(desc && !document.getElementById(desc)){const d=document.createElement('div');d.id=desc;d.className='error';d.setAttribute('role','alert');el.insertAdjacentElement('afterend',d);}el.addEventListener('input',()=>{if(el.checkValidity()){el.removeAttribute('aria-invalid');const dd=el.getAttribute('aria-describedby');if(dd){const de=document.getElementById(dd);if(de)de.textContent='';}});});}

Test je pagina nu met onze WCAG checker/validator, installeer de plugin en neem gerust contact op via het contactformulier — we reageren binnen 24 uur.

Previous Post Next Post

Geef een reactie

Je e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *