WCAG-succescriteria · Level AAA

WCAG 2.4.12: Focus niet verduisterd (uitgebreid)

WCAG 2.4.12 vereist dat wanneer een UI-component toetsenbordfocus krijgt, geen enkel deel van die component wordt verborgen door door de auteur gecreëerde content — het gefocuste element moet volledig zichtbaar zijn. Dit verbeterde (AAA) criterium elimineert de gedeeltelijke zichtbaarheid die is toegestaan bij de AA-tegenhanger, zodat toetsenbordgebruikers altijd precies kunnen zien waar de focus is.

Wat Deze Regel Betekent

WCAG 2.4.12 — Focus Niet Verduisterd (Uitgebreid) — is de AAA-tegenhanger van WCAG 2.4.11 (Focus Niet Verduisterd, AA). Waar het AA-criterium toestaat dat een gefocust component gedeeltelijk zichtbaar is, eist het AAA-criterium dat het gefocuste component volledig zichtbaar is — geen enkel deel ervan mag worden verborgen door door de auteur gecreëerde content wanneer het toetsenbordfocus ontvangt.

In praktische termen betekent dit dat wanneer een gebruiker met Tab naar een interactief element gaat, zoals een link, knop, formulierveld of aangepaste widget, het volledige begrenzingsgebied van dat element niet verduisterd mag worden door een sticky header, vaste footer, modale overlay, cookiebanner, chatwidget of andere content die de auteur op de pagina heeft geplaatst. De regel richt zich specifiek op door de auteur gecreëerde content; het W3C maakt een expliciete uitzondering voor content die de gebruiker zelf heeft verplaatst om de focusindicator te verduisteren — bijvoorbeeld een zwevend paneel dat de gebruiker voor het gefocuste element heeft gesleept. In dat geval is de auteur niet verantwoordelijk.

Een voldoende resultaat onder 2.4.12 vereist dat bij het ontvangen van focus het volledige gefocuste component zichtbaar is binnen de viewport en niet wordt bedekt door een sticky, fixed of absoluut gepositioneerd element dat door de pagina-auteur wordt beheerd. Een onvoldoende resultaat treedt op wanneer enig deel van de zichtbare begrenzing van het gefocuste element wordt verborgen achter dergelijke overlays — zelfs één enkele pixel van de focusring of het component zelf die wordt afgeknipt, telt als een fout op AAA-niveau.

Het is belangrijk te begrijpen wat 2.4.12 niet dekt. Het schrijft geen specifieke stijl voor de focusindicator voor (dat wordt behandeld door 2.4.11 en 2.4.7). Het vereist niet dat focusindicatoren een minimale contrastverhouding hebben (gedekt door 2.4.13). Het behandelt specifiek de ruimtelijke relatie tussen het gefocuste element en andere content op de pagina — het laagprobleem dat het vaakst ontstaat door fixed en sticky positioning in CSS.

Betrokken HTML-elementen omvatten elk focusbaar of tabbable element: <a>, <button>, <input>, <select>, <textarea>, <details>, elementen met tabindex, en aangepaste interactieve widgets die met ARIA-rollen zijn gebouwd. Het criterium is van toepassing in alle browsercontexten, inclusief iframes, dialogen en route-overgangen in single-page applications.

Waarom Het Belangrijk Is

Toetsenbordnavigatie is een primaire toegangs­methode voor een brede groep gebruikers. Mensen met motorische beperkingen — waaronder mensen die leven met aandoeningen zoals ALS, multiple sclerose, cerebrale parese of RSI — zijn volledig afhankelijk van het toetsenbord of schakelaccess-apparaten in plaats van een muis. Blinde en slechtziende gebruikers die schermlezers gebruiken, navigeren ook met het toetsenbord, en hoewel hun ondersteunende technologie de focuspositie hoorbaar aankondigt, zijn ziende toetsenbordgebruikers volledig afhankelijk van de visuele focusindicator om zich op de pagina te oriënteren.

Wanneer het gefocuste element wordt verduisterd, zelfs gedeeltelijk, ervaren deze gebruikers een frustrerende en mogelijk desoriënterende situatie: de pagina lijkt helemaal geen gefocust element te hebben, of de gebruiker moet raden waar hij of zij zich in het document bevindt. Op AA-niveau (2.4.11) wordt gedeeltelijke zichtbaarheid getolereerd — ten minste een deel van het component is zichtbaar en biedt een aanwijzing. Het AAA-criterium elimineert dit compromis volledig, in de erkenning dat zelfs een gedeeltelijk verborgen focusindicator gemist kan worden door gebruikers met verminderde contrastgevoeligheid, tunnelvisie of cognitieve aandoeningen die het scannen van een scherm zwaarder maken.

Beschouw een concreet scenario: een Turkse e-commercewebsite gebruikt een vaste navigatiebalk van 80px hoog bovenaan de viewport en een sticky cookietoestemmingsbanner van 60px hoog onderaan. Een gebruiker die met Tab door productkaarten navigeert, kan merken dat de boven- of onderrand van de gefocuste kaart — inclusief de focusring — onder een van deze vaste vlakken schuift. Onder WCAG 2.4.11 (AA) slaagt de site als een deel van de kaart nog zichtbaar is. Onder 2.4.12 (AAA) moet de volledige kaart volledig zichtbaar zijn. Dit onderscheid is betekenisvol: een gedeeltelijk verborgen knoplabel in combinatie met een gedeeltelijk verborgen focusring kan het voor een slechtziende gebruiker daadwerkelijk onmogelijk maken om te bepalen welk element actief is of welke actie het zal uitvoeren.

Volgens de Wereldgezondheidsorganisatie hebben wereldwijd ongeveer 2.2 miljard mensen een vorm van visuele beperking, en motorische beperkingen treffen nog honderden miljoenen meer. Verbeteringen in toetsenbordtoegankelijkheid komen niet alleen deze groepen ten goede, maar ook power users die voor snelheid de voorkeur geven aan toetsenbordnavigatie, gebruikers op apparaten zonder aanwijsapparaat en gebruikers in situaties waarin de fijne motoriek tijdelijk is beperkt.

Naast toegang voor mensen met een beperking verbetert volledig zichtbare focus de algemene bruikbaarheid en verlaagt het de supportkosten. Wanneer alle gebruikers — inclusief mensen zonder beperking — de focuspositie duidelijk kunnen volgen, verbeteren de voltooiingspercentages van formulieren en nemen de foutpercentages af. Voor sites die zich richten op de Turkse markt, geeft het aantonen van AAA-conformiteit blijk van een volwassen toegankelijkheidsprogramma en bouwt het vertrouwen op bij zowel gebruikers als institutionele inkoopteams.

Gerelateerde Axe-core Regels

WCAG 2.4.12 wordt geclassificeerd als een criterium dat handmatige tests vereist en maakt deel uit van de aanvullingen in WCAG 2.2. Er is geen volledig geautomatiseerde axe-core-regel die deze overtreding betrouwbaar kan detecteren, en begrijpen waarom dat zo is, is belangrijk voor teams die hun testpijplijnen opbouwen.

  • Handmatige inspectie — focus-not-obscured-enhanced (geen geautomatiseerde regel): Geautomatiseerde toegankelijkheidsscanners zoals axe-core werken op de statische DOM of een snapshot van de gerenderde staat. Detecteren of een gefocust element wordt verduisterd vereist: (1) het simuleren van toetsenbordfocus op elk interactief element in volgorde, (2) het berekenen van het begrenzingsvlak van het element na focus-geïnduceerd scrollen, (3) het identificeren van alle fixed en sticky gepositioneerde elementen en hun begrenzingsvlakken, en (4) het testen op geometrische overlap. Hoewel gedeeltelijke automatisering theoretisch mogelijk is, maakt de dynamische aard van scrollgedrag, CSS-scroll-padding, smooth scrolling en door JavaScript aangestuurde focusbeheer dit in de praktijk zeer onbetrouwbaar. Een gefocust element dat bij één viewportgrootte perfect zichtbaar is, kan bij een andere volledig verduisterd zijn. axe-core markeert dit criterium als iets dat menselijke beoordeling vereist en markeert bevindingen als "needs review" in plaats van automatische overtredingen. Testers moeten handmatig met Tab door elk interactief element gaan en bij elke relevante viewportbreedte visueel volledige zichtbaarheid bevestigen.
  • scrollable-region-focusable (axe-regel): Hoewel deze axe-regel niet direct is gekoppeld aan 2.4.12, markeert hij elementen binnen scrollbare regio’s die focusbaar zijn maar mogelijk niet correct in beeld scrollen. Het is een gerelateerd signaal dat wijst op scrollbeheerproblemen die ervoor kunnen zorgen dat focus wordt verduisterd door sticky headers of footers — de meest voorkomende faalmodus voor 2.4.12.

Omdat geautomatiseerde tools 2.4.12-overtredingen niet betrouwbaar kunnen opsporen, moeten organisaties handmatige toetsenbord-walkthroughs opnemen in hun QA-proces, idealiter bij meerdere viewportgroottes en met alle persistente UI-lagen (navigatiebalken, chatwidgets, cookiebanners, GDPR-meldingen) actief.

Hoe te Testen

  1. Geautomatiseerde baselinescan: Voer axe DevTools of Lighthouse uit op de pagina om gerelateerde problemen te identificeren, zoals scrollable-region-focusable-overtredingen of CSS-overflowproblemen. Deze bevindingen zijn weliswaar geen directe 2.4.12-overtredingen, maar wijzen op delen van de pagina die het meest waarschijnlijk focus-verduisterende problemen veroorzaken. Filter in axe DevTools op WCAG 2.2-criteria en bekijk alle items met "needs review" die betrekking hebben op focuszichtbaarheid.
  2. Identificeer alle persistente overlaycontent: Breng vóór toetsenbordtesten visueel elk element met position: fixed of position: sticky op de pagina in kaart — doorgaans navigatiebalken, cookiebanners, chatwidgets, floating action buttons en footertoolsbalken. Noteer hun hoogtes en posities zodat u weet welke zones van de viewport ze innemen.
  3. Toetsenbordnavigatie-walkthrough: Begin bovenaan de pagina (of na het sluiten van een eerste modal) en druk herhaaldelijk op Tab om de focus door elk interactief element te verplaatsen. Controleer bij elke focusstop dat het volledige gefocuste element — inclusief de zichtbare focusindicator (omlijning of ring) — zich volledig binnen het onbedekte viewportgebied bevindt. Accepteer geen gedeeltelijke zichtbaarheid. Als enig deel van het element of de focusring achter een fixed element verdwijnt, noteer dit als een 2.4.12-fout.
  4. Omgekeerde navigatie: Herhaal de walkthrough met Shift+Tab om achteruit te navigeren. Vaste footers worden vaak gemist bij tests die alleen vooruit gaan, maar kunnen elementen verduisteren bij navigatie in omgekeerde richting.
  5. Schermlezertests met NVDA + Firefox: Start NVDA, open Firefox en navigeer met Tab. Wanneer NVDA de focus op een element aankondigt, controleer visueel of het element volledig zichtbaar is. De focusmodus van NVDA scrollt elementen niet automatisch vrij van fixed lagen, waardoor overtredingen kunnen verschillen van het browser-native gedrag.
  6. Schermlezertests met VoiceOver + Safari (macOS/iOS): Schakel VoiceOver in en gebruik Tab (of veeg op iOS) om te navigeren. Het scrollbeheer van Safari wijkt soms af van dat van Chromium, waardoor focusstaten die in Chrome niet verduisterd zijn, hier wel aan het licht kunnen komen.
  7. Responsieve viewporttests: Herhaal de toetsenbord-walkthrough bij gangbare breakpoints — 320px, 768px, 1024px en 1440px breed. Sticky elementen worden vaak hoger, lager of anders gepositioneerd bij verschillende breakpoints, waardoor andere zones risico lopen.
  8. Test na gebruikersinteracties: Open dropdownmenu’s, klap accordeons uit, activeer modals en navigeer naar nieuwe routes in single-page applications. Hervat na elke statuswijziging de Tab-navigatie en controleer opnieuw de volledige focuszichtbaarheid, omdat dynamische content vaak nieuwe fixed overlays introduceert.

Hoe te Oplossen

Sticky header die gefocuste links verduistert — Onjuist

<!-- Fixed header zonder scrollcompensatie -->
<header style='position:fixed; top:0; height:80px; background:#fff; width:100%;'>
  <nav>...</nav>
</header>

<main>
  <!-- Wanneer Tab deze link nabij de bovenkant van main bereikt, wordt hij bedekt door de header -->
  <a href='/products'>View all products</a>
</main>

Sticky header die gefocuste links verduistert — Juist

<!-- scroll-padding-top zorgt ervoor dat gefocuste elementen vrij van de fixed header in beeld scrollen -->
<style>
  html {
    /* Stem deze waarde af op de hoogte van je fixed header */
    scroll-padding-top: 88px; /* 80px header + 8px ademruimte */
  }
</style>

<header style='position:fixed; top:0; height:80px; background:#fff; width:100%;'>
  <nav>...</nav>
</header>

<main style='margin-top:80px;'>
  <!-- Focus scrollt het element nu volledig vrij van de header -->
  <a href='/products'>View all products</a>
</main>

Cookiebanner die interactieve elementen aan de onderkant van de viewport bedekt — Onjuist

<!-- Cookiebanner vast aan de onderkant, geen scrollcompensatie -->
<div id='cookie-banner' style='position:fixed; bottom:0; height:72px; width:100%; background:#222;'>
  <button>Accept All</button>
  <button>Manage Preferences</button>
</div>

<footer>
  <!-- Deze links onderaan de pagina worden bedekt door de cookiebanner -->
  <a href='/privacy'>Privacy Policy</a>
  <a href='/terms'>Terms of Service</a>
</footer>

Cookiebanner die interactieve elementen aan de onderkant van de viewport bedekt — Juist

<!-- Voeg scroll-padding-bottom en body padding toe om de bannerhoogte te compenseren -->
<style>
  html {
    scroll-padding-bottom: 80px; /* 72px banner + 8px ademruimte */
  }
  body {
    padding-bottom: 80px; /* Voorkom dat content permanent onder de banner staat */
  }
</style>

<div id='cookie-banner' style='position:fixed; bottom:0; height:72px; width:100%; background:#222;'>
  <button>Accept All</button>
  <button>Manage Preferences</button>
</div>

<footer>
  <!-- Links scrollen nu volledig in het onbedekte viewportgebied -->
  <a href='/privacy'>Privacy Policy</a>
  <a href='/terms'>Terms of Service</a>
</footer>

JavaScript-focusbeheer dat geen rekening houdt met fixed lagen — Onjuist

<!-- SPA-routewijziging: focus verplaatst naar heading maar scrollIntoView negeert header -->
<script>
function navigateTo(section) {
  const heading = document.querySelector('#' + section + ' h2');
  heading.setAttribute('tabindex', '-1');
  heading.focus();
  // scrollIntoView zonder offset — heading scrollt achter de fixed header
  heading.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
</script>

JavaScript-focusbeheer dat geen rekening houdt met fixed lagen — Juist

<!-- Gebruik scroll-margin-top op het doelelement, of compenseer scrollY handmatig -->
<style>
  .focus-target {
    /* scroll-margin-top verschuift de scrollpositie van dit element vanaf de bovenkant */
    scroll-margin-top: 96px;
  }
</style>

<script>
function navigateTo(section) {
  const heading = document.querySelector('#' + section + ' h2');
  heading.setAttribute('tabindex', '-1');
  // scroll-margin-top op het element verzorgt automatisch de visuele offset
  heading.classList.add('focus-target');
  heading.focus();
  // scrollIntoView respecteert nu scroll-margin-top en maakt de fixed header vrij
  heading.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
</script>

Veelvoorkomende Fouten

  • scroll-padding-top instellen op body in plaats van op html: De CSS-eigenschap scroll-padding moet worden toegepast op de scrollcontainer. Voor scrollen op paginaniveau is de scrollcontainer het html-element, niet body. Toepassing op body heeft in de meeste browsers geen effect en is een van de meest voorkomende implementatiefouten.
  • Een vaste pixelwaarde hardcoderen voor scroll-padding-top die niet overeenkomt met de werkelijke headerhoogte bij alle breakpoints: Wanneer de header op mobiel inklapt naar een kleinere hoogte of op desktop wordt uitgebreid met een secundaire navigatiebalk, wordt de statische offset onjuist. Gebruik CSS-custom properties die via JavaScript worden bijgewerkt of gebruik calc() met relatieve eenheden om de waarde in sync te houden.
  • scroll-margin-top vergeten op in-page anchordoelen: Zelfs wanneer de globale scroll-padding-top correct is voor Tab-navigatie, kunnen anchordoelen die programmatisch focus ontvangen (bijv. skiplinks, hash-navigatie in SPA’s) nog steeds onder de header terechtkomen, tenzij scroll-margin-top ook op die specifieke elementen is ingesteld.
  • De cookiebanner sluiten zonder opnieuw te testen: Veel teams testen toetsenbordnavigatie pas nadat de cookiebanner is geaccepteerd. Omdat de banner de onderkant van de viewport inneemt, kunnen focusbare elementen die onderaan zijn uitgelijnd alleen verduisterd worden zolang de banner actief is. Test altijd met alle persistente UI-lagen in hun volledig weergegeven staat.
  • Slechts op één viewportbreedte testen: Sticky elementen veranderen vaak van hoogte, worden zichtbaar of verdwijnen volledig bij verschillende breakpoints. Een fout op 375px hoeft niet op 1440px voor te komen, en omgekeerd. Alleen op één grootte testen mist een substantieel deel van de reële overtredingen.
  • overflow: hidden gebruiken op een bovenliggend container om focusindicatoren af te knippen: Wanneer een kaartcomponent of container overflow: hidden heeft, wordt de browser-standaard focusomlijning op kindelementen afgeknipt bij de containergrens. Hierdoor kan focus in de elementinspectie van DevTools volledig zichtbaar lijken, terwijl deze voor de gebruiker visueel wordt afgesneden.
  • Aannemen dat schermlezers scroll automatisch afhandelen, zodat visuele tests niet nodig zijn: Hoewel schermlezers het gefocuste element hoorbaar aankondigen, zijn ziende toetsenbordgebruikers — inclusief gebruikers van schermvergrotingshulpmiddelen — volledig afhankelijk van de visuele positie. Een visueel verduisterde focusstatus is een echte fout, ongeacht het gedrag van schermlezers.
  • Modale dialogen en drawer-overlays niet testen: Wanneer een modal wordt geopend en de focus erin wordt geplaatst, kan de backdrop of de modal-chrome zelf het eerste gefocuste element in de dialoog verduisteren. Dit komt vooral vaak voor bij drawer-achtige panelen die vanaf de zijkant of onderkant inschuiven.
  • Derdepartijwidgets zoals live chat-bubbels en interstitiële advertentiebanners negeren: Zwevende chatwidgets (bijv. Intercom, Zendesk) en vaste promotiebanners die door tagmanagers worden geïnjecteerd, zijn door de auteur gecreëerde content en vallen binnen de reikwijdte van dit criterium. Teams zien deze vaak over het hoofd omdat ze buiten de hoofdcodebase worden beheerd.
  • Uitsluitend vertrouwen op geautomatiseerde toegankelijkheidsscans en het ticket sluiten: Omdat 2.4.12 handmatige tests vereist, bevestigt een schone axe-core-scan geen conformiteit. Toegankelijkheidstickets sluiten op basis van alleen geautomatiseerde resultaten zal dit criterium consequent missen.

Relatie met de Turkse Toegankelijkheidsregelgeving

De Turkse Presidential Circular 2025/10, gepubliceerd in het Staatsblad nr. 32933 op 21 June 2025, stelt bindende toegankelijkheidseisen voor web en mobiel vast voor een brede groep entiteiten die in Turkije actief zijn. De circulaire neemt WCAG 2.1 niveau AA als basisconformiteitsstandaard, wat betekent dat WCAG 2.4.12 — als een WCAG 2.2 AAA-criterium — niet direct verplicht is onder de huidige regelgeving. De relatie met het Turkse toegankelijkheidskader is echter om verschillende redenen belangrijk.

De entiteiten die onder Presidential Circular 2025/10 vallen, omvatten overheidsinstellingen en -organen op alle niveaus, e-commerceplatforms, banken en aanbieders van financiële diensten, ziekenhuizen en zorgorganisaties, telecombedrijven met 200,000 of meer abonnees, reisbureaus, particuliere vervoersbedrijven en particuliere scholen die zijn gemachtigd door het Ministry of National Education (MoNE). Voor al deze organisaties is het behalen van WCAG 2.1 AA-conformiteit een wettelijke verplichting, en wordt verwacht dat de circulaire wordt gehandhaafd via auditmechanismen die door de relevante toezichthoudende instanties worden beheerd.

Hoewel AAA-conformiteit niet door de circulaire wordt vereist, hebben organisaties in gereguleerde sectoren sterke praktische redenen om WCAG 2.4.12-conformiteit na te streven. Ten eerste is het Turkse regelgevingslandschap in ontwikkeling: de circulaire vormt een aanzienlijke opschaling van de handhaving van toegankelijkheid ten opzichte van eerdere richtlijnen, en toekomstige herzieningen kunnen WCAG 2.2 overnemen of het conformiteitsniveau verhogen. Organisaties die nu AAA-praktijken opbouwen, zijn beter gepositioneerd voor regelgevingswijzigingen. Ten tweede geven aanbestedingsprocessen in de publieke sector en toegang tot de EU-markt steeds vaker de voorkeur aan leveranciers die verbeterde toegankelijkheidsprogramma’s kunnen aantonen, en documentatie van AAA-conformiteit biedt een concurrentievoordeel.

Ten derde, en het meest direct relevant voor WCAG 2.4.12, behandelt het criterium een faalmodus die onevenredig veel invloed heeft op gebruikers van ondersteunende technologie in Turkije — een populatie die op enkele miljoenen mensen wordt geschat wanneer motorische, visuele en cognitieve beperkingen samen worden geteld. Banken, ziekenhuizen en e-governmentportalen die sterk leunen op vaste navigatiechrome en persistente notificatielagen zijn precies de sites waar focus-verduisterende fouten het meest voorkomen. Investeren in volledige WCAG 2.4.12-conformiteit toont een oprechte inzet om alle gebruikers te bedienen, sluit aan bij de geest van de presidential circular, zelfs waar de letter dat nog niet vereist, en vermindert het juridische en reputatierisico naarmate de Turkse handhaving volwassen wordt.

Voor organisaties die de Accsible overlay SDK gebruiken, biedt het platform tooling om toetsenbordfocuspaden te auditen en conflicten met sticky positioning te identificeren, ter ondersteuning van zowel de verplichte AA-eisen van Presidential Circular 2025/10 als vrijwillige AAA-verbeteringen zoals WCAG 2.4.12.