WCAG integreren in je webdesignproces

Toegankelijke formulieren: praktische implementatie van WCAG in HTML, ARIA en JavaScript

Formulieren falen in de praktijk vaak door ontbrekende labels, onduidelijke foutmeldingen, slechte focusmanagement en verkeerd gebruik van ARIA. Dit leidt tot afgehaakte gebruikers, frustratie bij schermlezergebruikers en mislukte conversies.

Wij lossen dit op met concrete, testbare patterns: complete HTML-structuren, bijpassende CSS voor zichtbare focus- en foutstates, en JavaScript-voorbeelden voor inline validatie en correcte ARIA-updates. Test direct met onze WCAG checker, probeer de plugin en stel vragen via het contactformulier (antwoord binnen 24 uur).

Het probleem in de praktijk

Veelvoorkomende fouten

  • Labels ontbreken of worden als placeholder gebruikt in plaats van echte <label>-elementen.
  • Foutmeldingen zijn niet gekoppeld aan velden (geen aria-describedby) en worden niet aangekondigd door schermlezers.
  • Focus springt niet naar het foutveld; keyboard gebruikers weten niet waar ze naartoe moeten.
  • Visuele focus ontbreekt of is niet contrastrijk, waardoor toetsenbordgebruikers verdwalen.
  • ARIA-attributen worden verkeerd gebruikt (bijv. aria-hidden op interactieve elementen).

Zo los je dit op in code

Basis HTML-structuur: semantisch en screenreader-vriendelijk

Gebruik altijd echte labels, voeg helpertekst en foutmeldingen toe met ID’s en koppel ze via aria-describedby. Voor groepsvelden gebruik <fieldset> en <legend>.

<form id="signup-form" novalidate><div class="form-row"><label for="email">E-mailadres</label><input id="email" name="email" type="email" required aria-describedby="email-help email-error" /><small id="email-help">We sturen een bevestiging naar dit adres.</small><div id="email-error" class="error" aria-live="polite"></div></div><div class="form-row"><label for="password">Wachtwoord</label><input id="password" name="password" type="password" minlength="8" required aria-describedby="password-help password-error" /><small id="password-help">Minimaal 8 tekens.</small><div id="password-error" class="error" aria-live="polite"></div></div><button type="submit">Aanmelden</button></form>

CSS: zichtbare focus en foutstijlen

Gebruik focus-visible voor toetsenbordgebruikers en contrastrijke foutstates.

.form-row input:focus{outline:3px solid #005fcc;outline-offset:2px;} .error{color:#a00000;margin-top:4px;} input[aria-invalid="true"]{border:2px solid #a00000;box-shadow:0 0 0 3px rgba(160,0,0,0.1);}

JavaScript: inline validatie en ARIA-updates (testbaar)

Voorkom default browsermeldingen, valideren on submit en live, zet aria-invalid en werk aria-describedby bij. Announce fouten via aria-live of focus naar het eerste foutveld.

document.getElementById('signup-form').addEventListener('submit',function(e){e.preventDefault();const form=this;let firstError=null;clearErrors(form);const email=form.querySelector('#email');const password=form.querySelector('#password');if(!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email.value)){setError(email,'Voer een geldig e-mailadres in');firstError=firstError||email;}if(password.value.length<8){setError(password,'Wachtwoord moet minstens 8 tekens zijn');firstError=firstError||password;}if(firstError){firstError.focus();return;}submitForm(form);});function setError(input,message){const err=document.getElementById(input.id+'-error');input.setAttribute('aria-invalid','true');err.textContent=message;err.setAttribute('role','alert');}function clearErrors(form){form.querySelectorAll('[aria-invalid="true"]').forEach(i=>i.removeAttribute('aria-invalid'));form.querySelectorAll('.error').forEach(e=>{e.textContent='';e.removeAttribute('role');});}function submitForm(form){ /* echte submit logica hier */ alert('Formulier klaar om te verzenden');}

Checklist voor developers

  • Zorg voor een <label for> per input; geen placeholder-only labels.
  • Koppel helpertekst en foutmeldingen met unieke ID’s en aria-describedby.
  • Gebruik aria-live="polite" of role="alert" voor dynamische foutmeldingen.
  • Zet aria-invalid="true" op velden met fouten.
  • Breng keyboard-focus naar het eerste foutveld (element.focus()).
  • Voorkom inline placeholders als vervanging van labels; ze verdwijnen bij input.
  • Test met toetsenbord, NVDA/VoiceOver en onze WCAG checker.

Tips voor designers en redacties

Design: focus en contrast

  • Ontwerp een duidelijke focusstate: minimaal 3px zichtbare rand of contrastieve schaduw.
  • Houd contrast van foutsteken en labels minimaal AA (4.5:1 voor tekst; 3:1 voor grote tekst).
  • Zorg voor voldoende ruimte tussen label, input en foutmelding.

Redactie: taal en helptekst

  • Schrijf korte, actiegerichte foutmeldingen die aangeven wat fout is en hoe te herstellen (bijv. “Wachtwoord te kort — voeg 2 tekens toe”).
  • Vermijd visuele hints als enige instructie; leg belangrijke instructies in zichtbare helpertekst met eigen ID gekoppeld aan het veld.
  • Gebruik duidelijke vermeldingen van verplichte velden (bijv. label + “verplicht” of aparte tekst, niet alleen kleur).

Hoe test je dit?

Automatisch en handmatig combineren

Begin met een automatische scan (onze WCAG checker). Gebruik daarnaast keyboard- en screenreader-tests voor echte gebruikersscenario’s.

Stappen voor handmatige tests

  1. Keyboard-only: navigeer naar elk formulier met Tab, activeer knoppen met Enter/Space, en controleer dat focus logisch is en zichtbaar blijft.
  2. Foutinjectie: submit met lege/ongeldige waarden en controleer dat foutmeldingen zichtbaar zijn, gekoppeld aan velden (aria-describedby) en worden aangekondigd.
  3. Screenreader: gebruik NVDA (Windows) of VoiceOver (macOS/iOS) en controleer label- en foutmelding-announce; gebruik rotor/landmarks om naar formulieren te springen.
  4. Color contrast: meet labels, helptekst en foutteksten met een contrasttool; streef naar WCAG AA of hoger.
  5. Responsiveness: test op mobiel; focus en foutmeldingen mogen niet buiten scherm vallen zonder scrollen.
  6. Gebruik onze WCAG checker en installeer de plugin voor CI-integratie en snelle feedback.

Testcases die je direct kunt uitvoeren

  • Voer formulier in en druk op submit zonder waarden — controleer of de eerste foutveld focus krijgt.
  • Schakel CSS uit en controleer of labels nog begrijpelijk zijn (progressieve verfijning).
  • Gebruik schermleesmodus en controleer of helpertekst en foutmelding worden voorgelezen.

Praktische how-to’s & snippets

How-to: focus naar eerste foutveld (kopieer/klaar)

function focusFirstError(form){const field=form.querySelector('[aria-invalid="true"], .error:empty ~ input');if(field){field.focus();field.scrollIntoView({block:'center'});} }

How-to: meertalige foutmeldingen (voorbeeld)

const messages={en:{email:'Enter a valid email'},nl:{email:'Voer een geldig e-mailadres in'}};function getMessage(code,lang){return messages[lang] && messages[lang][code] ? messages[lang][code] : messages['en'][code];}

Checklist om direct te implementeren

  • Voeg labels en aria-describedby toe aan elk inputveld.
  • Implementeer aria-live of role="alert" voor foutmeldingen.
  • Maak focus-management: focus naar eerste fout en gebruik :focus/:focus-visible CSS.
  • Verifieer met keyboard, screenreader en onze WCAG checker.
  • Integreer snelle checks in CI met onze plugin.

Wil je direct je site testen? Gebruik de WCAG checker op wcagtool.nl, installeer de plugin voor automatische scans en stuur vragen via het contactformulier — we antwoorden binnen 24 uur.

Laatste praktische tip: kopieer onderstaande one-liner in je project om bij submit automatisch focus naar het eerste foutveld te sturen en daarmee keyboard- en screenreadergebruikers direct te helpen.

document.getElementById('signup-form').addEventListener('submit',function(e){setTimeout(()=>{const f=this.querySelector('[aria-invalid="true"]');if(f){f.focus();f.scrollIntoView({block:'center'});}},0);});