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 uitgeschakeldaria-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 elementenreadonly: 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 keuzerondjesselected: 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 isaria-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 knoppenrole="dialog": Voor dialoogvenstersrole="slider": Voor schuifregelaarsrole="tablist",role="tab",role="tabpanel": Voor tabbladenrole="menu",role="menuitem": Voor menu’srole="listbox",role="option": Voor aangepaste keuzelijstenrole="search": Voor zoekgebiedenrole="region": Voor onderdelen met een naamrole="alert": Voor belangrijke meldingen
Voor toestand:
aria-expanded: Geeft aan of iets samengevouwen of uitgevouwen isaria-pressed: Voor knoppen die aan/uit kunnen staanaria-selected: Voor geselecteerde items in een lijstaria-checked: Voor aangepaste selectievakjes of keuzerondjesaria-current: Geeft aan welk item “actief” is, bijvoorbeeld de huidige pagina in een navigatiearia-invalid: Geeft aan dat een invoerveld een fout bevataria-disabled: Markeert een element als uitgeschakeld (let op: het element is nog steeds focusbaar, in tegenstelling tot hetdisabled-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: Minimumwaardearia-valuemax: Maximumwaardearia-valuenow: Huidige waardearia-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-labelledbyvoor de panelen - Rol: Expliciet aangegeven met
role="tablist",role="tab"enrole="tabpanel" - Toestand: Aangegeven met
aria-selected="true/false"en hethiddenattribuut
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-labelledbyvoor de inhoud - Rol: De standaard rol voor de knop en
role="region"voor de inhoud - Toestand:
aria-expanded="true/false"enhidden
Praktische tips voor het testen
Om je implementatie te controleren:
- Browser-inspectiehulpmiddelen: De toegankelijkheidsinspectie in Firefox of de accessibility tree en Lighthouse in Chrome
- Test zelf met een schermlezer: NVDA (Windows) of VoiceOver (Mac) zijn goede opties
- Test met automatische tools: axe Devtools (browser-extensie)
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!