WCAG-succescriteria · Level A

WCAG 2.1.1: Toetsenbord

WCAG 2.1.1 vereist dat alle functionaliteit die beschikbaar is via een muis of aanwijzer, even goed bedienbaar is met alleen een toetsenbord, zonder dat er specifieke timing voor toetsaanslagen nodig is. Dit criterium is fundamenteel voor gebruikers die geen muis kunnen gebruiken, zodat zij elke website of applicatie kunnen navigeren, ermee kunnen interageren en taken kunnen voltooien.

Wat Deze Regel Betekent

WCAG 2.1.1 (Keyboard) schrijft voor dat elke functionaliteit op een webpagina of in een applicatie bedienbaar moet zijn met een toetsenbordinterface. Dit betekent dat als een gebruiker op een knop kan klikken, een item kan slepen, kan hoveren om een menu te tonen, of met een muis met een ander element kan interageren, diezelfde actie ook uitsluitend met toetsenbordinvoer moet kunnen worden uitgevoerd — doorgaans met de toetsen Tab, Shift+Tab, Enter, Spatie en de pijltjestoetsen.

Het criterium is van toepassing op alle interactieve elementen: links, knoppen, formulierelementen, aangepaste widgets, modale dialogen, dropdownmenu’s, accordeons, carrousels, datumkiezers, drag-and-dropinterfaces, canvas-gebaseerde interacties en elk ander component dat reageert op gebruikersinvoer. Als content vereist dat een gebruiker een tekenpad uitvoert (waarbij het pad zelf de invoer is, niet alleen het eindpunt), is dat de enige formeel erkende uitzondering in WCAG. Buiten die nauwe uitzondering moet elke andere functionaliteit via het toetsenbord toegankelijk zijn.

Een pass betekent dat een gebruiker die alleen een toetsenbord gebruikt elk interactief element kan bereiken via Tab- of pijltjestoetsnavigatie, het kan activeren met Enter of Spatie, en de beoogde actie kan voltooien zonder dat er op enig moment een muis nodig is. Een fail treedt op wanneer een van de volgende situaties zich voordoet: een interactief element krijgt helemaal geen focus; het krijgt focus maar kan niet worden geactiveerd; een functie wordt uitsluitend getriggerd door een muisgebeurtenis zoals onmouseover of ondblclick zonder toetsenbordequivalent; of een scrollbare container is niet bereikbaar met het toetsenbord, waardoor content erin wordt opgesloten.

Het is belangrijk om WCAG 2.1.1 te onderscheiden van WCAG 2.1.2 (No Keyboard Trap). Criterium 2.1.1 zorgt ervoor dat toetsenbordgebruikers overal bij kunnen en alles kunnen gebruiken; criterium 2.1.2 zorgt ervoor dat toetsenbordgebruikers nooit vastzitten in een component. Beide moeten worden vervuld voor volledige Level A-conformiteit.

Waarom Het Belangrijk Is

Toetsenbordtoegankelijkheid is geen nicheprobleem. Naar schatting leeft 1 op de 4 volwassenen in de Verenigde Staten met een vorm van beperking, en motorische beperkingen — waaronder aandoeningen zoals de ziekte van Parkinson, multiple sclerose, ruggenmergletsels, RSI (repetitive strain injury), verschillen in ledematen en tremoren — verhinderen vaak dat gebruikers een standaardmuis of touchscreen kunnen bedienen. Deze gebruikers zijn volledig afhankelijk van toetsenborden, schakelbediening, sip-and-puff-apparaten, hoofdaanwijzers of andere ondersteunende technologieĂ«n die uiteindelijk toetsenbordinvoer emuleren op het niveau van het besturingssysteem.

Blinde en slechtziende gebruikers die vertrouwen op schermlezers zoals NVDA, JAWS of VoiceOver navigeren volledig via het toetsenbord. Als een element niet via het toetsenbord bereikbaar is, zal de schermlezer het nooit aankondigen, waardoor de content volledig onzichtbaar is voor die gebruiker. Volgens de Wereldgezondheidsorganisatie hebben wereldwijd minstens 2,2 miljard mensen een vorm van nabij- of verziendheidsstoornis.

Neem een concreet scenario: een gebruiker met vergevorderde reumatoĂŻde artritis in beide handen bezoekt een afrekenpagina van een e-commercesite. De op maat gemaakte selector voor betaalmethoden van de site is geĂŻmplementeerd als een reeks gestylede <div>-elementen die alleen reageren op muisklikken. De gebruiker kan met Tab naar de container gaan, maar geen enkele individuele optie krijgt focus en op Enter drukken doet niets. De gebruiker kan de aankoop niet voltooien. Dit is geen klein ongemak — het is een volledige uitsluiting van een commerciĂ«le transactie en het vormt zowel een juridisch risico als een scenario van aanzienlijk omzetverlies voor het bedrijf.

Naast beperkingen komt toetsenbordtoegankelijkheid ook ten goede aan power users die de voorkeur geven aan sneltoetsen, gebruikers in bedrijfs- of overheidsomgevingen waar muisgebruik door beleid is beperkt, en gebruikers met niet-standaard invoerapparaten. Het hangt ook positief samen met schone, semantische HTML-structuren die zoekmachines betrouwbaarder kunnen parsen, wat bijdraagt aan betere SEO-prestaties en de langetermijnonderhoudbaarheid van de codebase.

Gerelateerde Axe-core Regels

  • scrollable-region-focusable: Deze regel controleert of elk element met overflowcontent (d.w.z. het is scrollbaar) bereikbaar is via het toetsenbord. Wanneer een container CSS-eigenschappen heeft zoals overflow: auto of overflow: scroll, kunnen ziende muisgebruikers deze scrollen met een muiswiel of trackpad. Toetsenbordgebruikers moeten echter met Tab de container in kunnen gaan of pijltjestoetsen kunnen gebruiken om te scrollen. De regel markeert scrollbare regio’s die geen tabindex-attribuut en geen natuurlijk focusbaar kindelement hebben, wat betekent dat een gebruiker die alleen een toetsenbord gebruikt geen manier heeft om bij de overlopende content te komen. Geautomatiseerde detectie is hier betrouwbaar omdat axe de berekende stijlen en de DOM-boom kan inspecteren om elementen met scrollbare overflow te identificeren die geen toetsenbordfocus ondersteunen.
  • server-side-image-map: Deze regel markeert het gebruik van server-side imagemaps — HTML-<img>-elementen met het attribuut ismap. Server-side imagemaps sturen de ruwe pixelcoördinaten van een muisklik naar de server om te bepalen welke link is geactiveerd. Omdat de actie volledig afhankelijk is van pixelcoördinaten afkomstig van een aanwijzerapparaat, bestaat er geen toetsenbordequivalent mechanisme. In tegenstelling tot client-side imagemaps (die <map>- en <area>-elementen gebruiken en wel toetsenbordtoegankelijk kunnen worden gemaakt), zijn server-side imagemaps fundamenteel onverenigbaar met navigatie uitsluitend via het toetsenbord. Axe markeert elk <img ismap>-element als een fout op het gebied van toetsenbordtoegankelijkheid. Handmatige verificatie moet bevestigen of de imagemap de enige manier is om toegang te krijgen tot de onderliggende navigatie of functionaliteit.

Het is cruciaal om te begrijpen dat geautomatiseerde tools zoals axe-core slechts een deel van de fouten in toetsenbordtoegankelijkheid kunnen opsporen. Veel overtredingen vereisen handmatig testen omdat ze aangepaste JavaScript-eventlisteners, dynamisch focusbeheer of complexe interactiepatronen omvatten die statische analyse niet volledig kan beoordelen. Een voorbeeld: een knop die is geïmplementeerd als een <div> met een click-eventlistener kan via tabindex='0' focus krijgen, maar niet reageren op Enter- of Spatie-toetsaanslagen — een fout die axe niet altijd kan detecteren zonder de interactie uit te voeren.

Hoe te Testen

  1. Geautomatiseerde scan met axe DevTools of Lighthouse: Installeer de browserextensie axe DevTools voor Chrome of Firefox. Navigeer naar de te testen pagina en voer een volledige paginascan uit. Filter de resultaten op regels met de tags wcag2a en keyboard. Let specifiek op overtredingen van scrollable-region-focusable en server-side-image-map. Voer in Lighthouse (Chrome DevTools) een Accessibility-audit uit en bekijk de categorie “Keyboard”. Houd er rekening mee dat deze tools duidelijke structurele fouten naar voren brengen, maar niet alle problemen met aangepaste widgets zullen detecteren.
  2. Handmatige toetsenbordnavigatietest: Koppel uw muis los of leg deze weg. Begin vanuit de adresbalk van de browser en druk herhaaldelijk op Tab om vooruit te gaan langs alle focusbare elementen op de pagina. Druk op Shift+Tab om achteruit te gaan. Controleer voor elk interactief element — links, knoppen, invoervelden, aangepaste dropdowns, modals, sliders — dat: (a) het een zichtbare focusindicator krijgt; (b) op Enter of Spatie drukken het element activeert zoals verwacht; (c) elke resulterende dialoog of elk paneel ook met het toetsenbord kan worden genavigeerd en gesloten. Gebruik pijltjestoetsen binnen widgets die samengestelde patronen implementeren (menu’s, tablijsten, radiogroepen, listboxes).
  3. Schermlezer + toetsenbordtest met NVDA en Firefox: Start NVDA (gratis, Windows) en open Firefox. Gebruik de Browse Mode van NVDA (pijltjestoetsen) om de pagina te lezen en alle interactieve elementen te identificeren. Schakel over naar Focus Mode (Insert+Spatie of automatisch bij formuliervelden) om met besturingselementen te interageren. Controleer of aangepaste widgets hun rol, status en naam aankondigen en of alle functionaliteit zonder muis kan worden voltooid. Test alle scrollbare containers door te proberen er met Tab in te gaan en pijltjestoetsen te gebruiken om te scrollen.
  4. Schermlezertest met VoiceOver en Safari (macOS/iOS): Schakel VoiceOver in (Command+F5 op macOS). Gebruik VO+pijltje rechts om lineair door de pagina te navigeren. Gebruik Tab om tussen interactieve elementen te bewegen. Bevestig dat scrollbare regio’s bereikbaar zijn en dat geen enkele functionaliteit een veegbeweging of aanwijzerinteractie vereist zonder toetsenbordtoegankelijk alternatief.
  5. JAWS- en Chrome-test: Open met JAWS actief Chrome en navigeer naar de pagina. Gebruik de JAWS Virtual Cursor om door de content te bladeren en de Tab-toets om tussen interactieve elementen te bewegen. Test specifiek alle aangepaste JavaScript-widgets — accordeons, carrousels, modale dialogen, aangepaste selectievakjes — door ernaartoe te tabben en te proberen ze volledig met het toetsenbord te bedienen. Noteer elk element dat focus krijgt maar niet kan worden geactiveerd, of elke functionaliteit die alleen bereikbaar is via muis-hover.
  6. Specifieke test voor scrollbare regio’s: Identificeer alle containers op de pagina met zichtbare scrollbalken of die meer content bevatten dan hun zichtbare gebied. Probeer met Tab in elke container te gaan. Als Tab de focus niet in de container verplaatst en er geen focusbare kindelementen zijn, is de container waarschijnlijk een fout in toetsenbordtoegankelijkheid. Probeer op pijltjestoetsen te drukken terwijl de container of een nabijgelegen element focus heeft om te zien of scrollen mogelijk is.

Hoe te Herstellen

Scenario 1: Scrollbare Container — Onjuist

<!-- Scrollbare div zonder tabindex: toetsenbordgebruikers kunnen deze content niet scrollen -->
<div style='height: 200px; overflow-y: auto;'>
  <p>Long list of terms and conditions text...</p>
  <p>More text that overflows the container...</p>
</div>

Scenario 1: Scrollbare Container — Juist

<!-- Door tabindex='0' toe te voegen wordt de container focusbaar zodat toetsenbordgebruikers
     deze kunnen scrollen met pijltjestoetsen zodra hij focus heeft -->
<div
  tabindex='0'
  role='region'
  aria-label='Terms and Conditions'
  style='height: 200px; overflow-y: auto;'
>
  <p>Long list of terms and conditions text...</p>
  <p>More text that overflows the container...</p>
</div>

Scenario 2: Server-Side Image Map — Onjuist

<!-- ismap stuurt pixelcoördinaten naar de server — er bestaat geen toetsenbordequivalent -->
<a href='/map-handler'>
  <img src='navigation-map.png' ismap alt='Site navigation map' />
</a>

Scenario 2: Server-Side Image Map — Juist

<!-- Vervang door een client-side imagemap met <map>- en <area>-elementen.
     Elk <area>-element is focusbaar en met het toetsenbord te activeren. -->
<img
  src='navigation-map.png'
  alt='Site navigation map'
  usemap='#site-nav'
/>
<map name='site-nav'>
  <area shape='rect' coords='0,0,100,50' href='/home' alt='Home' />
  <area shape='rect' coords='100,0,200,50' href='/about' alt='About Us' />
  <area shape='rect' coords='200,0,300,50' href='/contact' alt='Contact' />
</map>

Scenario 3: Aangepaste Widget die Alleen Muisevents Gebruikt — Onjuist

<!-- div die als knop fungeert met alleen onclick: toetsenbordgebruikers die op Enter
     of Spatie drukken krijgen geen reactie -->
<div onclick='submitForm()'>Submit Order</div>

Scenario 3: Aangepaste Widget die Alleen Muisevents Gebruikt — Juist

<!-- Optie A: Gebruik een native <button> — die verwerkt toetsenbordactivatie standaard -->
<button type='submit' onclick='submitForm()'>Submit Order</button>

<!-- Optie B: Als een aangepast element nodig is, voeg tabindex, role en
     een keydown-listener toe voor Enter (13) en Spatie (32) -->
<div
  role='button'
  tabindex='0'
  onclick='submitForm()'
  onkeydown='if(event.key==="Enter"||event.key===" "){submitForm();}'
>
  Submit Order
</div>

Scenario 4: Alleen-Hover Dropdownmenu — Onjuist

<!-- Menu verschijnt alleen bij CSS :hover — toetsenbordfocus op de ouder
     toont het submenu niet -->
<nav>
  <ul>
    <li class='has-dropdown'>
      <a href='/products'>Products</a>
      <ul class='dropdown'> <!-- alleen zichtbaar bij :hover in CSS -->
        <li><a href='/products/a'>Product A</a></li>
        <li><a href='/products/b'>Product B</a></li>
      </ul>
    </li>
  </ul>
</nav>

Scenario 4: Alleen-Hover Dropdownmenu — Juist

<!-- Gebruik een knop om de dropdown te toggelen en beheer aria-expanded.
     CSS toont het submenu wanneer de knop aria-expanded='true' heeft.
     Toetsenbordgebruikers drukken op Enter/Spatie op de knop om het menu te openen. -->
<nav>
  <ul>
    <li class='has-dropdown'>
      <button
        aria-expanded='false'
        aria-controls='products-submenu'
        onclick='toggleMenu(this)'
      >
        Products
      </button>
      <ul id='products-submenu' hidden>
        <li><a href='/products/a'>Product A</a></li>
        <li><a href='/products/b'>Product B</a></li>
      </ul>
    </li>
  </ul>
</nav>

Veelvoorkomende Fouten

  • onclick gebruiken als enige eventhandler op een niet-natief element zonder een bijbehorende onkeydown- of onkeyup-handler toe te voegen — muisklikken triggeren onclick, maar toetsenbordactivatie op een <div> of <span> doet dat niet.
  • tabindex='0' toevoegen aan een aangepast interactief element maar vergeten role='button' (of een passende rol) toe te voegen, waardoor schermlezers het doel van het element niet aan de gebruiker communiceren.
  • Dropdownnavigatie bouwen die uitsluitend vertrouwt op de CSS-pseudoklasse :hover zonder een JavaScript-gestuurde toetsenbordtoggle, waardoor submenu’s onzichtbaar en onbereikbaar zijn voor toetsenbordgebruikers.
  • Drag-and-dropinterfaces implementeren — sorteerlijsten, kanbanborden, zones voor het uploaden van bestanden — zonder een toetsenbordtoegankelijke alternatieve methode, zoals met het toetsenbord geactiveerde verplaatsingscommando’s of een aparte besturing voor herschikking.
  • Scrollbare containers maken (zoals algemene-voorwaardenboxen, chatvensters of datatabellen in wrappers met vaste hoogte) zonder tabindex='0', waardoor toetsenbordgebruikers niet kunnen scrollen om alle content te bekijken.
  • <img ismap> gebruiken voor navigatiecomponenten die zijn overgenomen uit legacy-codebases zonder ze te vervangen door client-side imagemaps of standaardnavigatielinks.
  • tabindex='-1' toepassen op interactieve elementen om ze uit de natuurlijke Tab-volgorde te verwijderen zonder een programmatische focusbeheerstrategie te bieden, wat resulteert in besturingselementen die permanent onbereikbaar zijn met het toetsenbord.
  • Functionaliteit uitsluitend triggeren op mouseenter-, mouseleave- of mousemove-events (tooltips, previews, contextmenu’s) zonder equivalente focus-, blur- of toetsenbordgebeurtenisalternatieven.
  • Aannemen dat een modale dialoog focus automatisch beheert — nalaten de focus naar de dialoog te verplaatsen wanneer deze wordt geopend en nalaten de focus terug te brengen naar het triggerende element wanneer deze wordt gesloten, waardoor toetsenbordgebruikers gedesoriĂ«nteerd raken op de pagina.
  • pointer-events: none in CSS instellen op een element dat via het toetsenbord toegankelijk zou moeten zijn, wat, hoewel het niet direct van invloed is op toetsenbordgedrag, vaak gepaard gaat met JavaScript-patronen die ook toetsenbordinteractie blokkeren.

Relatie met de Toegankelijkheidsregelgeving van Turkije

De Turkse Presidential Circular 2025/10, gepubliceerd in het Staatsblad nr. 32933 op 21 juni 2025, stelt verplichte eisen voor webtoegankelijkheid vast die zijn afgestemd op WCAG 2.1 Level AA. WCAG 2.1.1 (Keyboard) is een criterium op Level A, wat het in de hoogste prioriteitscategorie van vereiste naleving plaatst. Conformiteit op Level A is de absolute minimumbasislijn — als een site niet voldoet aan de criteria van Level A, wordt deze als niet-toegankelijk beschouwd, ongeacht andere verbeteringen.

Volgens de circulaire verschillen de termijnen voor naleving per type entiteit: publieke instellingen en overheidsinstanties moeten binnen één jaar na de publicatiedatum van de circulaire conformiteit bereiken, terwijl private sectorentiteiten die onder de regeling vallen twee jaar hebben om te voldoen.

De entiteiten die onder Presidential Circular 2025/10 vallen, omvatten een brede dwarsdoorsnede van Turkse digitale diensten: e-commerceplatforms, publieke instellingen en ministeries, banken en financiële instellingen, ziekenhuizen en zorgaanbieders, telecommunicatiebedrijven met 200,000 of meer abonnees, gelicentieerde reisbureaus, private transportbedrijven en particuliere scholen die zijn gemachtigd door het Ministry of National Education (MoNE).

Voor al deze entiteiten betekent het niet voldoen aan WCAG 2.1.1 dat gebruikers die afhankelijk zijn van het toetsenbord — waaronder burgers met motorische beperkingen, oudere gebruikers en schermlezergebruikers — geen toegang hebben tot hun kern-digitalediensten. Dit is een directe schending van de regelgeving. In praktische termen zou een e-commercesite waar de checkoutflow niet met het toetsenbord kan worden voltooid, of een patiĂ«ntenportaal van een ziekenhuis waar het maken van afspraken muisinteractie vereist, in strijd zijn met de vereisten van de circulaire.

Organisaties die onder de circulaire vallen, zouden een audit van de toetsenbordtoegankelijkheid moeten uitvoeren als eerste stap in hun programma voor toegankelijkheidsherstel. Omdat fouten in WCAG 2.1.1 vaak architectonisch van aard zijn — geworteld in de keuze van HTML-elementen, patronen voor eventbinding en standaardinstellingen van componentframeworks — kan herstel codewijzigingen vereisen in plaats van alleen configuratieaanpassingen. De overlay-SDK van Accsible kan helpen bij het signaleren en verhelpen van veelvoorkomende hiaten in toetsenbordtoegankelijkheid op de JavaScript-laag, maar teams zouden ook structurele oplossingen in hun broncode moeten nastreven om robuuste, controleerbare conformiteit te bereiken die een regelgevende toets kan doorstaan.