Naam, rol, waarde: de taal van hulptechnologieën

Als je een website gebruikt zonder het scherm te kunnen zien. Hoe weet je dan:

  • Op welke knop je gaat klikken?
  • Wat je in een formulierveld moet invullen?
  • Of een selectievakje aangevinkt is of niet?

Dit is precies waarom naam, rol, waarde zo belangrijk is. Het zorgt dat schermlezers (en andere hulptechnologieën) deze informatie kunnen presenteren.

Wat is WCAG 4.1.2 eigenlijk?

Succescriterium 4.1.2 Naam, rol, waarde valt onder het principe “Robuust” en stelt:

Voor alle componenten van de gebruikersinterface (inclusief, maar niet uitsluitend voor formulierelementen, links en door scripts gegenereerde componenten), kunnen de naam (name) en rol (role) door software bepaald worden; toestanden (states), eigenschappen (properties) en waarden (values) die door de gebruiker ingesteld kunnen worden, kunnen door software ingesteld worden; en kennisgeving van veranderingen in deze items is beschikbaar voor user agents, met inbegrip van hulptechnologieën.

Simpel gezegd: Alle bedieningselementen op je website (zoals links, knoppen, formuliervelden, enz.) moeten in de code informatie bevatten die hulptechnologieën goed kunnen begrijpen. Deze informatie bestaat uit:

  • Naam: Hoe heet het? (bijv. “Zoeken”, “E-mailadres”, “Menu”)
  • Rol: Wat is het? (bijv. link, knop, invoerveld, keuzelijst)
  • Toestand: Hoe staat het erbij? (bijv. uitgeschakeld, aangevinkt, uitgevouwen)
  • Waarde: Wat is de huidige inhoud? (bijv. “Nederland”, “70%”, de ingevoerde tekst)

Dit succescriterium is vooral bedoeld voor ontwikkelaars die hun eigen componenten bouwen. Standaard HTML-elementen (zoals <a>, <button> en <input>) voldoen automatisch aan dit criterium als je ze volgens specificatie gebruikt.

Naam, rol, toestand en waarde voor verschillende componenten

Laten we eens kijken naar hoe je naam, rol, toestand en waarde toepast bij de meest voorkomende componenten.

Links

Naam van links

De naam van een link is wat een schermlezer presenteert om de gebruiker te vertellen waar de link naar verwijst. Standaard is dit alle content tussen de begintag en de eindtag van het <a>-element. Doorgaans is dit ook de zichtbare linktekst.

<a href="contact.html">
  Neem contact met ons op
</a>

Gebruik je een afbeelding als link? Dan vormt het tekstalternatief de linktekst.

<a href="home.html">
  <img src="home-icon.png" alt="Home">
</a>

Rol van links

Als je een <a>-element gebruikt in combinatie met het href-attribuut, dan is de rol “link” automatisch ingesteld.

Knoppen

Naam van knoppen

De naam van een knop is standaard de content tussen de begintag en de eindtag van het <button>-element:

<button type="submit">
  Verstuur formulier
</button>

Voor knoppen met alleen een afbeelding vormt het tekstalternatief de toegankelijke naam:

<button type="submit">
  <img src="send-icon.png" alt="Verstuur">
</button>

Rol van knoppen

Knoppen hebben standaard de rol “button”. Als je een <button>-element gebruikt, dan is deze rol automatisch ingesteld.

Toestand van knoppen

Knoppen kunnen verschillende toestanden hebben:

  • disabled: Markeert een knop als uitgeschakeld
  • aria-pressed: Voor knoppen die aan/uit kunnen staan
<!-- Inactieve knop -->
<button type="submit" disabled>
  Verstuur formulier
</button>

<!-- Toggle met aria-pressed -->
<button type="button" aria-pressed="false" onclick="toggleFunction()">
  Pauzeer
</button>

Het aria-pressed-attribuut geeft aan of een knop in- of uitgeschakeld is zoals in een toggle.

Formulierelementen

Naam van formulierelementen

De naam van een formulierelement komt van het bijbehorende <label>-element. Koppel dit label aan het element.

<label for="gebruikersnaam">
  Gebruikersnaam
</label>
<input type="text" id="gebruikersnaam" name="gebruikersnaam">

Rol van formulierelementen

Formulierelementen hebben verschillende standaardrollen, afhankelijk van het type:

  • <input type="text">: invoerveld
  • <input type="checkbox">: selectievakje
  • <input type="radio">: keuzerondje
  • <input type="range">: schuifregelaar
  • <select>: keuzelijst
  • <textarea>: tekstvak

Zorg dat je het juiste type gebruikt voor het doel van het formulierelement.

Toestand van formulierelementen

Formulierelementen kunnen ook inactief of alleen-lezen zijn:

  • disabled: Voor inactieve elementen
  • readonly: Voor alleen-lezen velden
<!-- Inactief invoerveld -->
<input type="text" value="Niet bewerkbaar" disabled>

<!-- Alleen-lezen invoerveld -->
<input type="text" value="Alleen bekijken" readonly>

Het verschil is belangrijk: een disabled veld kan de gebruiker niet bereiken met het toetsenbord. Een readonly veld wel. Gebruik readonly als de gebruiker de waarde moet kunnen kopiëren of als de waarde mee moet worden verstuurd bij het verzenden van het formulier.

Waarde van formulierelementen

De waarde van een formulierelement is wat de gebruiker heeft ingevoerd of geselecteerd. Zorg dat de huidige waarde altijd duidelijk is:

  • checked: Voor aangevinkte selectievakjes en keuzerondjes
  • selected: Voor geselecteerde opties in keuzelijsten
  • ingevoerde tekst: Voor invoervelden en tekstvakken
<!-- Selectievakje dat is aangevinkt -->
<input type="checkbox" value="Nederland" checked>

<!-- Keuzelijst met een geselecteerde optie -->
<select>
  <option>Kies een land</option>
  <option selected>Nederland</option>
  <option>België</option>
</select>

Maatwerk componenten

Bij complexe componenten zoals tabbladen, accordeons of carrousels worden naam, rol en waarde een stuk ingewikkelder. Dan komt ARIA (Accessible Rich Internet Applications) van pas. Maar onthoud altijd de eerste regel van ARIA: Gebruik geen ARIA als je native HTML-elementen kunt gebruiken.

Hier zijn de belangrijkste ARIA-attributen voor naam, rol en waarde:

Voor naam:

  • aria-label: Geeft een naam, bijvoorbeeld als er geen zichtbare tekst is
  • aria-labelledby: Verwijst naar de ID van een ander element dat als label dient
<!-- aria-label -->
<button aria-label="Sluiten">
  X
</button>

<!-- aria-labelledby -->
<h2 id="dialogTitle">
  Instellingen wijzigen
</h2>
<div role="dialog" aria-labelledby="dialogTitle">
  <!-- Dialooginhoud -->
</div>

Lees meer over hoe browsers de toegankelijke naam berekenen.

Voor rol:

Het role-attribuut bepaalt de functie van een element. Veelgebruikte rollen zijn:

  • role="button": Voor aangepaste knoppen
  • role="dialog": Voor dialoogvensters
  • role="slider": Voor schuifregelaars
  • role="tablist", role="tab", role="tabpanel": Voor tabbladen
  • role="menu", role="menuitem": Voor menu’s
  • role="listbox", role="option": Voor aangepaste keuzelijsten
  • role="search": Voor zoekgebieden
  • role="region": Voor onderdelen met een naam
  • role="alert": Voor belangrijke meldingen

Voor toestand:

  • aria-expanded: Geeft aan of iets samengevouwen of uitgevouwen is
  • aria-pressed: Voor knoppen die aan/uit kunnen staan
  • aria-selected: Voor geselecteerde items in een lijst
  • aria-checked: Voor aangepaste selectievakjes of keuzerondjes
  • aria-current: Geeft aan welk item “actief” is, bijvoorbeeld de huidige pagina in een navigatie
  • aria-invalid: Geeft aan dat een invoerveld een fout bevat
  • aria-disabled: Markeert een element als uitgeschakeld (let op: het element is nog steeds focusbaar, in tegenstelling tot het disabled-attribuut)
  • aria-busy: Geeft aan dat een element wordt bijgewerkt
<!-- aria-expanded -->
<button aria-expanded="false">
  Meer opties
</button>

<!-- aria-pressed -->
<button aria-pressed="true">
  Geluid aan
</button>

<!-- aria-selected -->
<div role="option" aria-selected="true">
  Nederland
</div>

<!-- aria-checked -->
<div role="checkbox" aria-checked="true" tabindex="0">
  Akkoord met voorwaarden
</div>

<!-- aria-current -->
<nav>
  <a href="/" aria-current="page">
    Home
  </a>
  <a href="/producten">
    Producten
  </a>
</nav>

<!-- aria-invalid -->
<input type="email" id="email" aria-invalid="true" aria-describedby="email-fout">
<p id="email-fout">
  Vul een geldig e-mailadres in.
</p>

<!-- aria-disabled -->
<button aria-disabled="true">
  Versturen niet mogelijk
</button>

<!-- aria-busy -->
<div aria-busy="true">
  Resultaten worden geladen...
</div>

Voor waarde:

Elementen zoals schuifregelaars en voortgangsbalken hebben een numerieke waarde. Gebruik deze attributen om de waarde te communiceren:

  • aria-valuemin: Minimumwaarde
  • aria-valuemax: Maximumwaarde
  • aria-valuenow: Huidige waarde
  • aria-valuetext: Tekstuele weergave van de waarde
<!-- Aangepaste schuifregelaar -->
<div role="slider" aria-label="Volume" aria-valuemin="0" aria-valuemax="100" aria-valuenow="70" tabindex="0"></div>

<!-- Met aria-valuetext voor duidelijkere beschrijving -->
<div role="slider" aria-label="Temperatuur" aria-valuemin="16" aria-valuemax="30" aria-valuenow="21" aria-valuetext="21 graden Celsius" tabindex="0"></div>

Voorbeelden

Voorbeelden van wanneer ARIA nuttig kan zijn:

Tabbladen (voorbeeld)

<div role="tablist" aria-label="Productinformatie">
  <button role="tab" 
          id="tab-spec" 
          aria-selected="true" 
          aria-controls="panel-spec">
    Specificaties
  </button>
  <button role="tab" 
          id="tab-reviews" 
          aria-selected="false" 
          aria-controls="panel-reviews">
    Reviews
  </button>
</div>

<div id="panel-spec" 
     role="tabpanel" 
     aria-labelledby="tab-spec">
  <!-- Inhoud specificaties -->
</div>

<div id="panel-reviews" 
     role="tabpanel" 
     aria-labelledby="tab-reviews" 
     hidden>
  <!-- Inhoud reviews -->
</div>

In dit voorbeeld:

  • Naam: Komt van de tekst in de tabknoppen en aria-labelledby voor de panelen
  • Rol: Expliciet aangegeven met role="tablist", role="tab" en role="tabpanel"
  • Toestand: Aangegeven met aria-selected="true/false" en het hidden attribuut

Accordeon (voorbeeld)

<div class="accordion">
  <h3>
    <button aria-expanded="false" 
            aria-controls="section1-content" 
            id="section1-header">
      Veelgestelde vragen
    </button>
  </h3>
  <div id="section1-content" 
       role="region" 
       aria-labelledby="section1-header" 
       hidden>
    <!-- Accordeon inhoud -->
  </div>
</div>

In dit voorbeeld:

  • Naam: De knoptekst en aria-labelledby voor de inhoud
  • Rol: De standaard rol voor de knop en role="region" voor de inhoud
  • Toestand: aria-expanded="true/false" en hidden

Praktische tips voor het testen

Om je implementatie te controleren:

  1. Browser-inspectiehulpmiddelen: De toegankelijkheidsinspectie in Firefox of de accessibility tree en Lighthouse in Chrome
  2. Test zelf met een schermlezer: NVDA (Windows) of VoiceOver (Mac) zijn goede opties
  3. Test met automatische tools: axe Devtools (browser-extensie)

Lees meer over hulpmiddelen

Conclusie

Door standaard HTML-elementen te gebruiken waar mogelijk en ARIA waar nodig, maak je je website toegankelijker voor iedereen. En het mooie is: veel van deze technieken verbeteren ook de gebruikerservaring voor mensen zonder functiebeperking.

Heb je nog vragen over WCAG 4.1.2 of andere succescriteria? Laat het me weten!​​​​​​​​​​​​​​​​