WCAG-succescriteria · Level A
WCAG 4.1.1: Ontleden (Verouderd in WCAG 2.2)
WCAG 4.1.1 Parsing vereist dat webcontent vrij is van grote HTML/XML-fouten—zoals dubbele ID’s—die ertoe kunnen leiden dat ondersteunende technologieën de pagina verkeerd interpreteren of niet kunnen verwerken. Hoewel deze succescriterium is verouderd in WCAG 2.2, blijven de onderliggende axe-core-regels actief en duiden overtredingen nog steeds op een reëel toegankelijkheidsrisico.
Wat Deze Regel Betekent
WCAG 4.1.1 Parsing is oorspronkelijk ontworpen om ervoor te zorgen dat user agents, waaronder browsers en ondersteunende technologieën, webcontent nauwkeurig konden parseren en interpreteren. Het criterium vereiste dat pagina’s die zijn opgesteld in opmaaktalen zoals HTML of XML aan vier structurele voorwaarden voldeden: elementen moeten volledige begin- en eindtags hebben; elementen moeten genest zijn volgens hun specificaties; elementen mogen geen dubbele attributen bevatten; en alle ID’s die in de content worden gebruikt, moeten uniek zijn.
In WCAG 2.2 heeft het W3C dit criterium formeel gedepricieerd. De reden hiervoor was dat moderne browsers zeer veerkrachtig zijn geworden tegen onjuiste HTML en de meeste structurele fouten automatisch corrigeren voordat ze de accessibility tree bereiken. Daardoor veroorzaken veel van de oorspronkelijke zorgen—zoals niet-afgesloten tags of onjuist geneste elementen—in hedendaagse omgevingen geen praktische schade meer voor ondersteunende technologieën.
Deprecatie betekent echter niet dat de zorgen van het criterium volledig zijn verdwenen. Het W3C merkt expliciet op dat dubbele ID-attributen een betekenisvol toegankelijkheidsprobleem blijven. Wanneer twee of meer elementen dezelfde id-waarde delen, moet de browser een willekeurige beslissing nemen over welk element wordt geassocieerd met ARIA-referenties, labelassociaties of fragmentlinks. Deze ambiguïteit kan ertoe leiden dat schermlezers onjuiste content aankondigen, interactieve bedieningselementen overslaan of formulierlabels helemaal niet blootleggen. De slaagvoorwaarde van het criterium wordt daarom tegenwoordig het best begrepen als: er komen geen dubbele ID-waarden in de DOM voor. Een pagina faalt dit criterium wanneer ID’s worden gedupliceerd op manieren die programmatische associaties verbreken waar ondersteunende technologieën op vertrouwen.
Officiële uitzonderingen in de WCAG-specificatie zijn minimaal. Het criterium is van toepassing op content die is opgesteld in opmaaktalen; het is niet van toepassing op content die wordt gegenereerd door scriptingomgevingen waar de auteur geen directe controle heeft over het uitvoerformaat. In de praktijk zijn ontwikkelaars echter verantwoordelijk voor de uiteindelijke gerenderde DOM, ongeacht de technologiestack die wordt gebruikt om deze te produceren.
Waarom Het Belangrijk Is
Dubbele ID’s lijken misschien een klein onderhoudsprobleem, maar de gevolgen voor gebruikers van ondersteunende technologie kunnen ernstig zijn. Schermlezers zoals JAWS, NVDA en VoiceOver vertrouwen op de accessibility tree van de browser, die op zijn beurt afhankelijk is van correct opgeloste ID-referenties om de relaties tussen interface-elementen op te bouwen. Wanneer een ID wordt gedupliceerd, lost de browser referenties doorgaans alleen op naar het eerste overeenkomende element in documentvolgorde, terwijl latere elementen met dezelfde ID stilzwijgend worden genegeerd.
Voor blinde en slechtziende gebruikers kan dit betekenen dat een formulierveld wordt aangekondigd zonder label, of dat een foutmelding die via aria-describedby aan een invoerveld is gekoppeld, nooit wordt voorgelezen. Denk aan een afrekenformulier op een e-commercesite waar de velden voor verzendadres en factuuradres beide ID’s gebruiken zoals city, zip en state. Een schermlezergebruiker die de factuursectie invult, kan het label uit de verzendsectie horen, wat leidt tot verwarring, fouten en mogelijk het afbreken van de transactie.
Voor gebruikers met cognitieve beperkingen betekenen kapotte labelassociaties dat de zichtbare tekst die zij op het scherm lezen niet overeenkomt met wat hun schermlezer of spraakbesturingssoftware aankondigt, wat een desoriënterende kloof creëert die de cognitieve belasting verhoogt.
Voor motorisch beperkte gebruikers die vertrouwen op spraakinvoersoftware zoals Dragon NaturallySpeaking, kunnen dubbele ID’s ertoe leiden dat spraakcommando’s die op een specifiek bedieningselement zijn gericht, het verkeerde element activeren, omdat de software intern mogelijk op ID-gebaseerde targeting gebruikt.
Naast de impact op mensen met een beperking beïnvloeden dubbele ID’s ook SEO: zoekmachinecrawlers die vertrouwen op fragmentidentificatoren voor het indexeren van specifieke paginasecties kunnen onjuiste content indexeren wanneer ID’s niet uniek zijn. De bruikbaarheid gaat ook voor alle gebruikers achteruit wanneer ankerlinks binnen de pagina naar de verkeerde locatie op de pagina navigeren.
Ongeveer 2,2 miljard mensen wereldwijd hebben volgens de Wereldgezondheidsorganisatie een vorm van visuele beperking. Een aanzienlijk deel van deze gebruikers is afhankelijk van schermlezers die direct worden beïnvloed door kapotte ID-associaties. Zorgen voor unieke ID’s is een van de inspanningsarmste en impactrijkste oplossingen die een developmentteam kan implementeren.
Gerelateerde Axe-core Regels
Drie axe-core-regels komen direct overeen met de zorgen die door WCAG 4.1.1 worden geadresseerd. Elke regel richt zich op een specifieke manifestatie van het probleem van dubbele ID’s:
- duplicate-id: Deze regel controleert de volledige DOM op elke
id-attribuutwaarde die op meer dan één element voorkomt. Hij markeert alle elementen na het eerste die een ID delen, ongeacht of die elementen interactief zijn of door ARIA worden gerefereerd. Dit is de meest brede van de drie regels en detecteert structurele overtredingen zelfs wanneer er geen expliciete ARIA-relatie in het spel is. Een veelvoorkomende trigger zijn componentgebaseerde frameworks die dezelfde herbruikbare component meerdere keren op een pagina renderen zonder unieke ID’s voor elke instantie te genereren. - duplicate-id-active: Deze regel vernauwt zijn focus tot dubbele ID’s op elementen die interactief of focusbaar zijn—knoppen, links, invoervelden en elk element met een niet-negatieve
tabindex. De toegankelijkheidsimpact is hier groter omdat ondersteunende technologieën en toetsenbordnavigatie beide afhankelijk zijn van de mogelijkheid om een actief bedieningselement ondubbelzinnig te identificeren. Wanneer een verzendknop en een niet-gerelateerd pictogram dezelfde ID delen, kunnen zowel tabvolgorde-aankondigingen als programmatisch focusbeheer stukgaan. - duplicate-id-aria: Dit is de meest kritieke van de drie regels. Deze markeert dubbele ID’s specifiek wanneer die ID’s worden gerefereerd door ARIA-attributen—
aria-labelledby,aria-describedby,aria-controls,aria-ownsen vergelijkbare relatie-attributen. Omdat deze attributen het primaire mechanisme zijn waarmee ondersteunende technologieën de relaties tussen elementen begrijpen, verbreken duplicaten hier direct de berekening van toegankelijke namen en rolsrelaties. Een fout voorbeeld zou twee<div>-elementen metid='dialog-title'zijn wanneer een modalaria-labelledby='dialog-title'gebruikt—de schermlezer zal het element aankondigen dat het eerst in de DOM voorkomt, wat mogelijk niet de bedoelde dialoogkop is.
Geautomatiseerde tools zijn zeer geschikt om dubbele ID’s te detecteren omdat de controle puur syntactisch is: de tool leest de DOM en vergelijkt ID-waarden. Voor dit criterium is geen handmatige test strikt vereist. Als ID’s echter dynamisch worden gegenereerd na gebruikersinteractie—bijvoorbeeld een infinite scroll die nieuwe content met herhaalde ID’s injecteert—kunnen geautomatiseerde scans die bij het laden van de pagina worden uitgevoerd, overtredingen missen die pas later verschijnen. In dergelijke gevallen moeten testers het dynamische gedrag activeren voordat ze scans uitvoeren, of de DOM monitoren met behulp van de ontwikkelaarstools van de browser na interacties.
Hoe te Testen
- Geautomatiseerde scan met axe DevTools: Open de pagina in Chrome of Firefox. Open DevTools (F12), ga naar het axe DevTools-paneel (of installeer de browserextensie) en voer een volledige paginascan uit. Filter de resultaten op de regels duplicate-id, duplicate-id-active en duplicate-id-aria. Elke overtreding vermeldt de getroffen elementen en hun dubbele ID-waarden. Exporteer het rapport indien nodig voor auditdocumentatie. Voor Lighthouse: voer een Lighthouse-toegankelijkheidsaudit uit vanuit het Lighthouse-tabblad in DevTools en zoek naar de audit “Document has multiple elements with the same id”.
- Controle via de browserconsole in DevTools: Open de browserconsole en voer het volgende JavaScript-fragment uit om alle dubbele ID’s op de huidige pagina te vinden:
const ids = [...document.querySelectorAll('[id]')].map(el => el.id); const dupes = ids.filter((id, i) => ids.indexOf(id) !== i); console.log([...new Set(dupes)]);Dit zal een array afdrukken van alle ID-waarden die meer dan eens voorkomen. Een lege array betekent dat er geen duplicaten aanwezig zijn. - Schermlezertest met NVDA en Firefox: Laad de pagina met NVDA actief. Navigeer naar een formulier dat velden bevat met labels die zijn gekoppeld via
for/idofaria-labelledby. Tab door elk veld en luister zorgvuldig of NVDA het juiste label aankondigt. Als een veld wordt aangekondigd zonder label, of met het verkeerde label uit een andere sectie, kan een dubbele ID de oorzaak zijn. Herhaal dit proces voor ARIA-landmarkregio’s, modale dialogen of widgets diearia-controlsofaria-describedbygebruiken. - VoiceOver en Safari op macOS: Schakel VoiceOver in (Command+F5). Gebruik de VoiceOver-rotor (Control+Option+U) om de lijst Form Controls of Links te openen en controleer of elk bedieningselement een uniek, correct aangekondigd label heeft. Navigeer in eventuele modale dialogen en bevestig dat de dialoogtitel correct wordt aangekondigd wanneer de dialoog wordt geopend.
- JAWS en Chrome: Open met JAWS actief de pagina en gebruik de JAWS-lijst met formuliervelden (Insert+F5) om alle formulierelementen en hun gekoppelde labels te bekijken. Controleer of niet twee velden dezelfde labeltekst delen wanneer ze verschillend zouden moeten zijn.
- Testen van dynamische content: Als de pagina infinite scroll, single-page-navigatie of modale dialogen gebruikt die via JavaScript worden geïnjecteerd, ga dan met deze functies aan de slag om nieuwe content in de DOM te laden en voer vervolgens de geautomatiseerde scan of het consolescript opnieuw uit om te controleren op duplicaten die door de dynamische content zijn geïntroduceerd.
Hoe te Herstellen
Dubbele formulierveld-ID’s in herhaalde secties — Onjuist
<!-- Shipping Address -->
<label for='city'>City</label>
<input type='text' id='city' name='shipping-city'>
<!-- Billing Address -->
<label for='city'>City</label>
<input type='text' id='city' name='billing-city'>
<!-- FAIL: Both inputs share id='city'. The second label's 'for' attribute
resolves to the first input, so screen readers announce the wrong field. -->
Dubbele formulierveld-ID’s in herhaalde secties — Juist
<!-- Shipping Address -->
<label for='shipping-city'>City</label>
<input type='text' id='shipping-city' name='shipping-city'>
<!-- Billing Address -->
<label for='billing-city'>City</label>
<input type='text' id='billing-city' name='billing-city'>
<!-- PASS: Each input has a unique ID scoped to its section.
Screen readers correctly announce each field's label. -->
Herbruikbare component meerdere keren gerenderd — Onjuist
<!-- Product Card 1 -->
<div class='product-card'>
<img id='product-img' src='shoe.jpg' alt='Running Shoe'>
<button id='add-to-cart' aria-describedby='product-desc'>Add to Cart</button>
<p id='product-desc'>Free shipping on orders over 500 TL.</p>
</div>
<!-- Product Card 2 (same template, duplicate IDs) -->
<div class='product-card'>
<img id='product-img' src='boot.jpg' alt='Hiking Boot'>
<button id='add-to-cart' aria-describedby='product-desc'>Add to Cart</button>
<p id='product-desc'>Free shipping on orders over 500 TL.</p>
</div>
<!-- FAIL: IDs duplicated across cards. aria-describedby on the second button
resolves to the <p> in the first card, not the second. -->
Herbruikbare component meerdere keren gerenderd — Juist
<!-- Product Card 1 -->
<div class='product-card'>
<img id='product-img-1' src='shoe.jpg' alt='Running Shoe'>
<button id='add-to-cart-1' aria-describedby='product-desc-1'>Add to Cart</button>
<p id='product-desc-1'>Free shipping on orders over 500 TL.</p>
</div>
<!-- Product Card 2 -->
<div class='product-card'>
<img id='product-img-2' src='boot.jpg' alt='Hiking Boot'>
<button id='add-to-cart-2' aria-describedby='product-desc-2'>Add to Cart</button>
<p id='product-desc-2'>Free shipping on orders over 500 TL.</p>
</div>
<!-- PASS: Each card's IDs are unique. ARIA references resolve correctly
within their own card. Use a counter, UUID, or slug-based strategy
to generate IDs in your component framework. -->
Modale dialoog met dubbele ARIA-labelreferentie — Onjuist
<!-- A generic heading used as a reusable ID -->
<h1 id='dialog-title'>Welcome</h1>
<div role='dialog' aria-modal='true' aria-labelledby='dialog-title'>
<h2 id='dialog-title'>Confirm Your Order</h2>
<p>Are you sure you want to place this order?</p>
<button>Confirm</button>
<button>Cancel</button>
</div>
<!-- FAIL: Two elements share id='dialog-title'. The dialog's
aria-labelledby resolves to the page <h1>, not the dialog heading.
Screen readers will announce 'Welcome' as the dialog name. -->
Modale dialoog met dubbele ARIA-labelreferentie — Juist
<h1>Welcome</h1>
<div role='dialog' aria-modal='true' aria-labelledby='confirm-dialog-title'>
<h2 id='confirm-dialog-title'>Confirm Your Order</h2>
<p>Are you sure you want to place this order?</p>
<button>Confirm</button>
<button>Cancel</button>
</div>
<!-- PASS: The dialog heading has a unique, descriptive ID.
aria-labelledby correctly identifies the dialog to screen readers
as 'Confirm Your Order'. -->
Veelvoorkomende Fouten
- Componentmarkup kopiëren en plakken zonder ID’s bij te werken: Ontwikkelaars dupliceren vaak een werkende HTML-sectie voor een tweede instantie (een tweede adresblok, een tweede tabpanel, een tweede accordion-item) en vergeten alle ID-waarden uniek te maken. Stel een naamgevingsconventie vast zoals
component-name-index(bijv.accordion-panel-1,accordion-panel-2) en handhaaf deze in code reviews. - Statische ID’s gebruiken in frameworkcomponenten zonder strategie voor unieke keys: React, Vue, Angular en vergelijkbare frameworks kunnen dezelfde component tientallen keren op één pagina renderen. Het gebruik van een hardgecodeerde
id='search-input'in een herbruikbare component zal evenveel duplicaten creëren als er instanties zijn. Leid ID’s altijd af van props, een teller of een utility zoalsuseId()in React 18+. - Vertrouwen op CSS-class targeting in plaats van de HTML te herstellen: Sommige ontwikkelaars omzeilen problemen met dubbele ID’s door JavaScript-selectors te wijzigen van
getElementByIdnaarquerySelectormet een class, terwijl ze de dubbele ID’s laten staan. Dit kan visueel gedrag herstellen, maar lost niets op aan de kapotte associaties in de accessibility tree. - Server-side templatingloops die in elke iteratie dezelfde ID genereren: Een Jinja2-, Blade- of Twig-template die
id='item-title'rendert binnen een{% for item in items %}-loop, produceert één duplicaat voor elk item in de lijst. Voeg altijd de loopindex of itemidentifier toe aan de ID:id='item-title-{{ loop.index }}'. - Dubbele ID’s in verborgen of off-screen elementen negeren: Elementen met
display: noneofvisibility: hiddenzijn nog steeds aanwezig in de DOM en hun ID’s zijn nog steeds geregistreerd. Een verborgen modaltemplate die een ID deelt met een zichtbaar element veroorzaakt dezelfde parseerfouten. Gebruik het attribuuthiddenof zorg ervoor dat verborgen templates unieke ID’s gebruiken. - Aannemen dat scoping naar een Shadow DOM het probleem oplost: ID’s binnen native Shadow DOM zijn gescope en conflicteren niet met ID’s in de light DOM of andere shadow roots. Veel componentbibliotheken gebruiken echter een polyfill of niet-standaard aanpak die geen echte scoping biedt. Controleer de daadwerkelijke DOM-uitvoer in plaats van uit te gaan van het gedrag van het framework.
- ID’s genereren op basis van door de gebruiker aangeleverde content zonder sanitisatie of deduplicatie: ID’s creëren op basis van productnamen, artikeltitels of andere dynamische tekst kan botsingen veroorzaken wanneer twee items dezelfde naam hebben (bijv. twee producten die beide “Classic” heten en beide
id='classic'genereren). Voeg altijd een unieke databasekey of index toe aan content-afgeleide ID’s. - Niet testen na client-side navigatie in single-page applications: SPA’s die nieuwe routecontent in de DOM injecteren zonder volledige paginareload kunnen ID’s van eerder bezochte routes opstapelen als oude content niet correct wordt verwijderd. Voer axe-scans uit na navigatie tussen routes, niet alleen bij de initiële load.
- ID’s in SVG-
<defs>- en<use>-elementen vergeten: SVG-spritepatronen die symbolen met ID’s definiëren in<defs>en deze vervolgens refereren met<use href='#icon-arrow'>kunnen dubbele ID’s creëren als dezelfde symbooldefinitie meerdere keren op een pagina wordt opgenomen. Centraliseer SVG-spritedefinities en neem ze slechts één keer op. - ID’s over het hoofd zien die worden gegenereerd door widgets van derden, chatplugins of analyticsscripts: Scripts van derden injecteren soms elementen met hardgecodeerde ID’s. Als je eigen code dezelfde ID gebruikt, ontstaat een conflict dat je tijdens ontwikkeling mogelijk niet opmerkt. Controleer de volledige gerenderde DOM inclusief content van derden en meld conflicten aan leveranciers of voorzie je eigen ID’s van een namespace om botsingen te voorkomen.
Relatie met de Toegankelijkheidsregelgeving van Turkije
De Turkse Presidential Circular 2025/10, gepubliceerd in het Staatsblad met nummer 32933 op 21 juni 2025, stelt verplichte webtoegankelijkheidseisen vast voor een brede groep publieke en private entiteiten die in Turkije actief zijn. De circulaire neemt WCAG 2.2 over als technische referentiestandaard, waarbij Level A-conformiteit de minimale wettelijke basis vormt voor alle betrokken entiteiten.
WCAG 4.1.1 Parsing is een Level A-criterium. Hoewel het W3C het in WCAG 2.2 heeft gedepricieerd, blijven de axe-core-regels die de primaire zorg—unieke ID’s—afdwingen actief en worden ze nog steeds gemarkeerd in toegankelijkheidsaudits die tegen WCAG 2.2 worden uitgevoerd. Turkse regelgevende audits en conformiteitsbeoordelingen die geautomatiseerde scantools gebruiken, zullen duplicate-id-overtredingen daarom markeren als potentiële Level A-fouten, ongeacht de gedepricieerde status van het criterium in de specificatie. Organisaties die compliance willen aantonen, moeten overtredingen met dubbele ID’s als blokkerende issues behandelen.
De entiteiten die onder Presidential Circular 2025/10 vallen, omvatten een breed scala aan publieke instellingen en organisaties in de private sector: alle centrale en lokale overheidsorganen en hun gelieerde agentschappen; banken en financiële instellingen die onder de Turkse bankwetgeving vallen; ziekenhuizen en private zorgaanbieders; telecomoperators met 200.000 of meer abonnees; e-commerceplatforms en online marktplaatsen; reisbureaus en touroperators; private vervoersbedrijven die onder publieke concessies opereren; en privéscholen en onderwijsinstellingen die zijn gemachtigd door het Ministry of National Education (MoNE).
De circulaire stelt een gefaseerde compliance-tijdlijn vast. Publieke instellingen moeten binnen één jaar na de publicatiedatum van de circulaire volledige Level A-conformiteit bereiken. Private entiteiten in de betrokken categorieën hebben twee jaar om hetzelfde niveau te halen. Niet-naleving stelt betrokken entiteiten bloot aan toezicht door de toezichthouder, mogelijke administratieve sancties en reputatierisico in een markt die steeds meer aandacht heeft voor toegankelijkheid.
Voor Turkse organisaties is het aanpakken van overtredingen met dubbele ID’s in het bijzonder relevant in contexten waar digitale formulieren, online betaalstromen, overheidsportalen en systemen voor het boeken van zorgafspraken worden gebruikt. Dit zijn precies de interfacetypen die het meest waarschijnlijk herhaalde formuliersecties, herbruikbare componenten en integraties met widgets van derden gebruiken die dubbele ID’s introduceren. Het opzetten van geautomatiseerd toegankelijkheidstesten—zoals het integreren van axe-core in CI/CD-pijplijnen—als onderdeel van het ontwikkelproces is zowel een technische best practice als een pragmatische strategie om blijvende naleving van de eisen van de circulaire te waarborgen.
