Semantische HTML en waarom het essentieel is voor WCAG

WCAG Toegankelijke Formulieren – Praktische Implementatie | wcagtool.nl

Toegankelijke formulieren: labels, errors en focuscorrectie in de praktijk

Formulieren zijn één van de meest voorkomende plekken waar WCAG-regels in de praktijk misgaan: ontbrekende labels, onbegrijpelijke foutmeldingen, slechte focusflow en ongebruiksvriendelijke ARIA-implementaties zorgen voor blokkades bij gebruikers met assistieve technologie. Dit artikel behandelt concrete, testbare oplossingen zodat developers, frontend engineers, UX/UI designers en redacties direct aan de slag kunnen.

Wij van wcagtool.nl vertalen WCAG naar werkbare code-snippets, checklists en teststappen. Test je site direct met onze WCAG checker/validator, download onze plugin voor CI-checks en neem contact op via het contactformulier — we reageren binnen 24 uur.

Het probleem in de praktijk

Ontbrekende of visueel verborgen labels, foutmeldingen die voor screenreaders onvindbaar zijn, en focus die niet naar het eerste foutveld springt: dat zijn de meest voorkomende issues. Ontwerpers kiezen vaak alleen een visueel hint in plaats van een echte label, en developers zetten aria-attrs zonder de juiste technieken voor focus- en live-announce. De uitkomst: formulieren die in visuele tests werken, maar falen voor toetsenbordgebruikers en screenreaders.

  • Labels niet gekoppeld via <label for=”id”> of aria-labelledby
  • Inline fouten zonder aria-describedby of role=”alert”
  • Geen focusmanagement na submit — gebruiker blijft “vast” staan
  • Contrast en focus-indicatoren niet zichtbaar

Test je formulier nu met onze WCAG checker/validator of installeer de plugin voor continue controle.

Zo los je dit op in code

1) Altijd correcte labels

Gebruik een <label> gekoppeld aan het input-id. Als je visueel geen label wilt tonen, gebruik een toegankelijke visually-hidden class.

<style>.sr-only{position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}</style><label for="email" class="sr-only">E-mailadres</label><input id="email" name="email" type="email" required aria-required="true">

2) Foutmeldingen die screenreaders en keyboarders zien

Gebruik aria-describedby op het input-element, en role=”alert” in de foutcontainer zodat assistive tech de fout aankondigt. Markeer velden met aria-invalid=”true”.

<div class="field"><label for="phone">Telefoonnummer</label><input id="phone" name="phone" type="tel" aria-describedby="phone-error" aria-invalid="false"><div id="phone-error" class="error" role="alert" aria-live="assertive" hidden>Voer een geldig telefoonnummer in</div></div>

3) Focus naar eerste foutveld na validatie

Gebruik JavaScript om client-side of server-side errors te focussen naar het eerste onjuist veld en zet aria-invalid. Dit verhoogt bruikbaarheid voor toetsenbordgebruikers en screenreaders.

function focusFirstError(errors){const first = document.querySelector('[data-error="true"],[aria-invalid="true"]') || document.querySelector('.error:first-of-type');if(first){const field = first.closest('.field')?.querySelector('input,select,textarea') || first;field.focus();}

4) Voorbeeld: eenvoudige client-side validatie (HTML + JS)

<form id="signup"><div class="field"><label for="name">Naam</label><input id="name" name="name" required aria-required="true" aria-describedby="name-error"><div id="name-error" class="error" role="alert" aria-live="assertive" hidden>Naam is verplicht</div></div><div class="field"><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" hidden>Vul een geldig e-mailadres in</div></div><button type="submit">Verstuur</button></form><script>document.getElementById('signup').addEventListener('submit',function(e){e.preventDefault();let firstError=null;['name','email'].forEach(id=>{const el=document.getElementById(id);const err=document.getElementById(id+'-error');if(!el.checkValidity()){el.setAttribute('aria-invalid','true');err.hidden=false;err.textContent=el.validationMessage;el.setAttribute('data-error','true');firstError=firstError||el}else{el.removeAttribute('aria-invalid');err.hidden=true;el.removeAttribute('data-error')} });if(firstError){firstError.focus();return} // submit form via AJAX of normale submit hier });</script>

5) Focus styles en zichtbaarheid

Zorg dat focus zichtbaar is, ook als de browser custom focus gebruikt. Gebruik :focus-visible voor moderne browsers en fallback voor focus.

input:focus,button:focus{outline:3px solid #005fcc;outline-offset:2px}input[aria-invalid="true"]{border-color:#d93025;background:#fff6f6}

Checklist voor developers

  • Labels: elk input-element heeft een zichtbare of sr-only <label> gekoppeld via for/id of aria-labelledby.
  • Fouten: gebruik aria-describedby en role=”alert” + aria-live voor fouttekst.
  • aria-invalid: zet op true bij ongeldige velden, false of verwijder bij validatie ok.
  • Focus: bij submit focus naar eerste foutveld en trap keyboard focus niet vast in modals.
  • Keyboard: alle interacties (submit, help, selecties) werken met Enter/TAB/Space.
  • Contrast: error states, placeholders en focus-indicatoren voldoen aan contrastregels.
  • HTML5-validatie: combineer native validation met custom messaging voor consistentie.
  • Test automatisering: run onze WCAG checker/validator en integreer de plugin in CI.

Gebruik de WCAG checker op https://wcagtool.nl en download onze plugin voor automatische builds.

Tips voor designers en redacties

1) Schrijf heldere, korte foutmeldingen

Vermijd generieke teksten als “Ongeldige invoer”. Geef oplossing: “Voer een geldig e-mailadres in zoals naam@voorbeeld.nl”. Plaats foutmelding direct in de context.

2) Visuele signalen én tekst

Kleur alleen is niet voldoende. Combineer kleur met iconen, expliciete tekst en focus-indicatoren. Test met grijswaarden en screenreaders.

3) Placeholder vs label

Gebruik placeholders alleen als voorbeeld, niet als vervanging van het label. Content-redacteuren: controleer dat voorbeeldteksten niet lijken op fouten of waarden.

4) Microcopy en instructies

Plaats instructies buiten het inputveld, gekoppeld via aria-describedby. Voor langere instructies gebruik een kort summier label en link naar uitgebreide hulp.

Hoe test je dit?

Handmatige tests (snel en effectief)

  • Toetsenbord-test: navigeer alleen met TAB en SHIFT+TAB, activeer alle controls met Enter/Space. Controleer dat focus zichtbaar blijft en logische volgorde klopt.
  • Screenreader-test: open NVDA/VoiceOver en loop door formulier, controleer of labels, foutmeldingen en aria-live aankondigingen hoorbaar/bruikbaar zijn.
  • Foutflow: verzend formulier met lege of ongeldige velden, controleer dat focus naar eerste fout springt en fouttekst wordt aangekondigd.
  • Contrast: controleer foutrand en focus-indicator met contrastcheckers (minimaal 3:1 voor UI-componenten, 4.5:1 voor tekst).

Automatische tests en CI

Gebruik onze WCAG checker/validator voor een snelle scan. Integreer de plugin in je build pipeline. Gebruik daarnaast axe-core in unit/e2e tests. Voorbeeld met Cypress + axe:

import 'cypress-axe';cy.visit('/formulier');cy.injectAxe();cy.checkA11y(null,{runOnly:{type:'tag',values:['wcag2aa']}});

Server-side validation en accessibility

Bij server-side errors: stuur fout-IDs terug en render foutblokken met aria-describedby en role=”alert”. Zorg dat de responsieve pagina de focus verplaatst naar het foutpaneel bij her-render.

// server response (JSON) { "errors": { "email":"Ongeldig e-mailadres" }, "focus":"email" } // client-side: focus naar field met id response.focus

Laatste praktische tip

Voeg deze utility-functie toe voor consistente foutafhandeling: zet aria-invalid, update fouttekst, toon role=”alert” en focus op eerste fout. Test direct met onze WCAG checker/validator en installeer de plugin voor continue monitoring. Vragen? Gebruik het contactformulier op wcagtool.nl — we antwoorden binnen 24 uur.

function showFieldError(id,message){const el=document.getElementById(id);const err=document.getElementById(id+'-error');if(!el||!err) return;err.textContent=message;err.hidden=false;err.setAttribute('role','alert');el.setAttribute('aria-invalid','true');el.setAttribute('aria-describedby',id+'-error');el.focus();}

Direct testen: voer je URL in op https://wcagtool.nl, download onze plugin en vraag ons om hulp via het contactformulier — reactie binnen 24 uur.

Previous Post Next Post

Geef een reactie

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