Toegankelijke formulieren

Formulieren op een website hebben een hele belangrijke rol: ze zorgen dat je kunt inloggen, bestellen, contact opnemen of solliciteren. Maar voor veel mensen zijn formulieren nog een frustrerende ervaring. Labels ontbreken, foutmeldingen zijn onduidelijk en het is niet altijd duidelijk wat je moet invullen.

Dit artikel laat je zien hoe het anders kan.

Start met duidelijke labels

Elk invoerveld heeft een beschrijvend en zichtbaar label nodig. Gebruikers moeten weten wat ze moeten invullen voordat ze beginnen.

Gebruik een <label>-element voor het label. Koppel elk label aan een invoerveld met het for-attribuut.

<label for="naam">
  Naam:
</label>
<input type="text" id="naam">

Let op: een placeholdertekst alleen is niet genoeg, omdat het:

  • verdwijnt als je begint met typen
  • vaak (standaard) te weinig contrast heeft
  • soms wordt verward met al ingevulde data

Markeer verplichte velden

Maak duidelijk welke velden verplicht zijn. Geef dit visueel aan met tekst, een sterretje (asterisk) of ander symbool. Gebruik daarnaast het required-attribuut.

<label for="email">
  E-mailadres (verplicht)
</label>
<input type="email" id="email" required>

Als je een sterretje of symbool wil gebruiken, leg dan bovenaan het formulier uit wat het betekent. Zo weet iedereen direct welke velden verplicht zijn.

Geef instructies vooraf

Vertel vooraf wat je verwacht, niet achteraf als het mis gaat. Plaats de instructie in het label of koppel deze aan het invoerveld met het aria-describedby-attribuut.

<label for="postcode">
  Postcode:
</label>
<span id="postcode-hint">
  Gebruik het formaat 1234 AB
</span>
<input type="text" id="postcode" aria-describedby="postcode-hint">

Bij een geboortedatum kun je het verwachte formaat tonen:

<label for="geboortedatum">
  Geboortedatum:
</label>
<span id="datum-hint">
  Gebruik het formaat DD-MM-JJJJ
</span>
<input type="text" id="geboortedatum" aria-describedby="datum-hint">

Groepeer gerelateerde velden

Gebruik het <fieldset>-element met <legend> om gerelateerde invoervelden te groeperen. Dit is vooral belangrijk bij keuzerondjes en selectievakjes.

<fieldset>
  <legend>
    Kies je pakket:
  </legend>
  <input type="radio" id="basis" name="pakket" value="basis">
  <label for="basis">
    Basis
  </label>
  <input type="radio" id="premium" name="pakket" value="premium">
  <label for="premium">
    Premium
  </label>
</fieldset>

De <legend> moet beschrijven waar de groep over gaat. Een schermlezer leest dit voor bij elk veld in de groep, zodat gebruikers de context behouden.

<fieldset>
  <legend>
    Selecteer je interesses:
  </legend>
  <input type="checkbox" id="sport" name="interesses" value="sport">
  <label for="sport">
    Sport
  </label>
  <input type="checkbox" id="muziek" name="interesses" value="muziek">
  <label for="muziek">
    Muziek
  </label>
  <input type="checkbox" id="lezen" name="interesses" value="lezen">
  <label for="lezen">
    Lezen
  </label>
</fieldset>

Help browsers met automatisch invullen

Browsers kunnen formulieren automatisch invullen als ze weten wat voor informatie je vraagt. Dit helpt niet alleen mensen met een cognitieve beperking, maar ook iedereen die snel een formulier wil invullen.

Gebruik het autocomplete-attribuut om aan te geven wat voor informatie je verwacht:

<label for="naam">
  Naam:
</label>
<input type="text" id="naam" autocomplete="name">
<label for="email">
  E-mailadres:
</label>
<input type="email" id="email" autocomplete="email">
<label for="tel">
  Telefoonnummer:
</label>
<input type="tel" id="tel" autocomplete="tel">
Veelgebruikte inputdoelen
  • name: Volledige naam
  • given-name: Voornaam
  • family-name: Achternaam
  • address-line1: Straatnaam
  • postal-code: Postcode
  • address-level2: Woonplaats
  • bday: Geboortedatum
  • email: E-mailadres
  • tel: Telefoonnummer

Bekijk de volledige lijst met inputdoelen

Gebruik autocomplete bij alle velden die persoonlijke informatie verzamelen.

Fouten afhandelen

Als er iets fout gaat, moet de gebruiker weten wát er mis is en wáár de fout zit.

Identificeer en beschrijf fouten in tekst

Gebruik drie elementen om fouten duidelijk te maken:

  1. Een zichtbare foutmelding in tekst
  2. Markeer het veld als ongeldig met aria-invalid="true"
  3. Koppel de foutmelding aan het veld met aria-describedby
<label for="telefoon">
  Telefoonnummer:
</label>
<input type="tel" id="telefoon" aria-invalid="true" aria-describedby="telefoon-fout" >
<span id="telefoon-fout">
  Vul je telefoonnummer in
</span>

Gebruik nooit alleen kleur om fouten aan te geven. Succescriterium 3.3.1 Foutidentificatie vereist een foutmelding in tekst die beschrijft wat er mis is.

Wees specifiek in foutmeldingen

Schrijf niet bij ieder veld “Dit veld is verplicht”, maar zorg dat de gebruiker begrijpt om welk veld het gaat:

<span id="naam-fout">
  Vul je naam in
</span>
<span id="email-fout">
  Vul je e-mailadres in
</span>
<span id="telefoon-fout">
  Vul je telefoonnummer in
</span>

Maak een samenvatting bij meerdere fouten

Help gebruikers door alle fouten bovenaan te tonen. Maak van de foutmeldingen links naar de bijbehorende velden.

<div role="alert">
  <h2>Er zijn fouten in het formulier</h2>
  <ul>
    <li><a href="#naam">Vul je naam in</a></li>
    <li><a href="#email">Vul je e-mailadres in</a></li>
    <li><a href="#telefoon">Vul je telefoonnummer in</a></li>
  </ul>
</div>

Zet de focus op de samenvatting of het eerste foutveld na het versturen.

Foutmeldingen in fieldsets

Bij gegroepeerde velden (zoals keuzerondjes) plaats je de foutmelding direct na de <legend>. Koppel deze aan de fieldset met aria-describedby op de fieldset zelf of op elk individueel veld.

<fieldset aria-describedby="betaling-fout">
  <legend>
    Kies je betaalmethode (verplicht)
  </legend>
  <span id="betaling-fout">
    Kies een betaalmethode
  </span>
  <input type="radio" id="ideal" name="betaling" value="ideal" aria-invalid="true">
  <label for="ideal">
    iDEAL
  </label>
  <input type="radio" id="creditcard" name="betaling" value="creditcard" aria-invalid="true">
  <label for="creditcard">
    Creditcard
  </label>
</fieldset>

of:

<fieldset>
  <legend>
    Kies je betaalmethode (verplicht)
  </legend>
  <span id="betaling-fout">
    Kies een betaalmethode
  </span>
  <input type="radio" id="ideal" name="betaling" value="ideal" aria-invalid="true" aria-describedby="betaling-fout" >
  <label for="ideal">
    iDEAL
  </label>
  <input type="radio" id="creditcard" name="betaling" value="creditcard" aria-invalid="true" aria-describedby="betaling-fout" >
  <label for="creditcard">
    Creditcard
  </label>
</fieldset>

Geef concrete suggesties

Vertel niet alleen wát er mis is, maar ook hóe je het kunt oplossen.

Bijvoorbeeld:

  • Bij een ongeldig e-mailadres: Het e-mailadres is niet geldig. Controleer of je een @ hebt gebruikt, bijvoorbeeld naam@voorbeeld.nl.
  • Bij een verkeerd datumformaat: Vul je geboortedatum in als DD-MM-JJJJ, bijvoorbeeld 15-03-1990
  • Bij een verkeerd postcodeformaat: Een postcode bestaat uit 4 cijfers en 2 letters, bijvoorbeeld 1234 AB
  • Bij een te lang telefoonnummer: Een telefoonnummer bestaat uit maximaal 10 cijfers. Laat de landcode weg, bijvoorbeeld 0612345678.

Wanneer géén suggesties geven?

Geef geen suggesties als dit de beveiliging in gevaar brengt. Bij een verkeerd wachtwoord vertel je niet wat er precies fout is.

Een volledig voorbeeld

Zo ziet een toegankelijk formulier eruit met alle elementen samen:

<form>
  <label for="naam">
    Naam (verplicht)
  </label>
  <input type="text" id="naam" autocomplete="name" required aria-invalid="true" aria-describedby="naam-fout" >
  <span id="naam-fout">
    Vul je naam in
  </span>
  <label for="email">
    E-mailadres (verplicht)
  </label>
  <input type="email" id="email" autocomplete="email" required aria-invalid="true" aria-describedby="email-fout" >
  <span id="email-fout">
    Het e-mailadres is niet geldig. Controleer of je een @ hebt gebruikt, bijvoorbeeld naam@voorbeeld.nl
  </span>
  <label for="geboortedatum">
    Geboortedatum:
  </label>
  <span id="datum-hint">
    Gebruik het formaat DD-MM-JJJJ
  </span>
  <input type="text" id="geboortedatum" autocomplete="bday" aria-describedby="datum-hint" >
  <button type="submit">
    Versturen
  </button>
</form>

Om te onthouden

Toegankelijke formulieren beginnen met de basis: duidelijke labels, heldere instructies en goede foutafhandeling. Met de juiste HTML-attributen help je niet alleen mensen met een beperking, maar maak je formulieren voor iedereen makkelijker te gebruiken.

Begin klein: Controleer eerst of alle velden labels hebben. Voeg dan autocomplete toe. Verbeter je foutmeldingen. Stap voor stap maak je je formulieren toegankelijker.

Gerelateerde succescriteria

Dit artikel behandelt vijf WCAG-succescriteria:

  1. 1.3.5 Identificeer het doel van de input (niveau AA)
  2. 2.4.6 Koppen en labels (niveau AA)
  3. 3.3.1 Foutidentificatie (niveau A)
  4. 3.3.2 Labels of instructies (niveau A)
  5. 3.3.3 Foutsuggestie (niveau AA)