Ai en wcag

AI-test: Herkent AI een div die doet alsof het een knop is?

Kan AI een klikbare div herkennen op een live website? Ik testte het met Claude Code en Playwright. Dit zijn de resultaten, de beperkingen en de tools die je nodig hebt.

Een div die doet alsof het een knop is

Een <div> met een onclick. Ziet eruit als een knop. Doet iets als je klikt. Maar druk op Tab en er gebeurt niets. Enter? Ook niets.

Voor een toetsenbordgebruiker bestaat deze knop niet.

Dit is de nummer 1 toetsenbordfout die ik tegenkom bij audits (WCAG 2.1.1). En de makkelijkste om op te lossen: vervang de div door een <button>. Maar kan AI dit probleem ook vinden? En dan niet in een losstaand stukje code, maar op een echte, live website?

Test 1: Code-analyse

Ik gaf Claude de volgende HTML, zonder hints:

<div class="btn-primary" onclick="addToCart(123)">In winkelwagen</div>

Mijn prompt: “Welke toegankelijkheidsproblemen zie je in deze code?”

Resultaat

Claude herkende het meteen:

“A <div> with an onclick handler is not keyboard accessible by default. It cannot be reached with Tab, it has no button role, and pressing Enter or Space will not activate it."

Het koppelt het probleem aan WCAG 2.1.1 (Toetsenbord) en geeft de juiste oplossing: gebruik een <button>.

Maar ik gaf AI een stukje code. Dat is de makkelijke variant. Kan AI dit ook vinden als je alleen een URL hebt?

Code-analyse: Claude herkent een div met onclick als toegankelijkheidsprobleem

Test 2: Een live website testen

Kan AI een webpagina bezoeken en deze fout opsporen? Ja, maar niet uit zichzelf. AI heeft een browser nodig.

Met Playwright (een tool voor browserautomatisering) kan Claude Code een echte browser openen, een webpagina bezoeken, en de DOM (de boomstructuur van alle elementen op een pagina) inspecteren. Dat ziet er zo uit:

const { chromium } = require("playwright");

const browser = await chromium.launch({ headless: true });
const page = await browser.newPage();
await page.goto("https://voorbeeld-webshop.nl");

// Zoek alle elementen met onclick die geen button of link zijn
const problemen = await page.evaluate(() => {
  const elementen = document.querySelectorAll("[onclick]");
  return Array.from(elementen)
    .filter((el) => {
      const tag = el.tagName.toLowerCase();
      return (
        tag !== "button" &&
        tag !== "a" &&
        tag !== "input" &&
        el.getAttribute("role") !== "button"
      );
    })
    .map((el) => ({
      tag: el.tagName.toLowerCase(),
      tekst: el.textContent?.trim().substring(0, 80),
      onclick: el.getAttribute("onclick"),
    }));
});

Dit script vindt elke div, span of ander niet-interactief element met een onclick-attribuut. Geen broncode nodig. Het test de live pagina.

Wat kan Playwright testen?

Playwright draait een echte Chromium-browser. Alle JavaScript wordt uitgevoerd, dus je ziet de pagina zoals een bezoeker die ziet – niet de broncode. Je kunt klikken, wachten tot een pop-up verschijnt, en dan de nieuwe HTML inspecteren. Pop-ups, uitklapmenu’s, tabbladen, content die pas laadt bij scrollen, iframes (ingesloten pagina’s). Het werkt allemaal.

Overzicht van wat Playwright wel en niet kan bij het testen van live websites

Waar gaat het mis?

Het grootste probleem: addEventListener. De meeste moderne websites gebruiken niet onclick="..." in de HTML. Ze koppelen click-events via JavaScript:

element.addEventListener("click", function () {
  addToCart(123);
});

Dit is onzichtbaar in de DOM. Er is geen onclick-attribuut om op te zoeken.

Je kunt wel zoeken naar signalen dat een element klikbaar bedoeld is:

  • Heeft het cursor: pointer in de berekende stijl?
  • Heeft het een class als “btn”, “button”, “clickable”?
  • Is het een <div> of <span> met tabindex="0" maar zonder role="button"?

Maar dat zijn heuristieken – vuistregels die vaak kloppen, maar niet altijd. Je krijgt vals positieven (elementen die er klikbaar uitzien maar het niet zijn) en vals negatieven (klikbare elementen zonder visuele hints).

Andere beperkingen:

BeperkingImpact
addEventListener is onzichtbaar in DOMHoog, de meeste moderne sites gebruiken dit
Je test altijd een paginastatus tegelijkMedium, ingelogd vs. uitgelogd, verschillende tabs
Gesloten Shadow DOM is ontoegankelijkLaag, komt zelden voor
Bot-detectie (Cloudflare e.d.)Medium, sommige sites blokkeren geautomatiseerde browsers
Pagina’s achter loginMedium, kan maar je moet credentials meegeven

Wat heb je nodig?

Om deze test zelf uit te voeren heb je drie dingen nodig:

  1. Node.js (versie 18 of hoger)
  2. Playwright (npm install playwright)
  3. Een Chromium-browser (npx playwright install chromium)

Geen broncode nodig, geen speciale toegang. Je test de website zoals een bezoeker die ziet.

De scorekaart

TestScoreToelichting
Code-analyse: div onclick herkennenGevondenClaude herkent het probleem in een code-snippet
Live website: inline onclick vindenGevondenPlaywright kan DOM doorzoeken op onclick-attributen
Live website: addEventListener vindenGemistOnzichtbaar in DOM, alleen via heuristieken te benaderen
Live website: dynamisch geladen divsGevondenPlaywright kan klikken, wachten, en nieuwe DOM inspecteren
Context begrijpen (waarom het fout is)GevondenClaude legt uit wat het betekent voor gebruikers

AI vindt dit probleem in code en bij inline onclick. Maar bij addEventListener (de manier waarop de meeste moderne websites werken) is het afhankelijk van heuristieken. Dat is een serieuze beperking.

Scorekaart test 1: drie keer gevonden, een keer gemist bij addEventListener

De fix

<!-- Niet doen -->
<div class="btn-primary" onclick="addToCart(123)">In winkelwagen</div>

<!-- Wel doen -->
<button class="btn-primary" type="button" onclick="addToCart(123)">
  In winkelwagen
</button>

Een <button> is standaard focusbaar, activeerbaar met Enter en Spatie, en heeft de juiste rol voor schermlezers. Gratis. Zonder extra code.

Wat ik hiervan leer

Claude begrijpt dit probleem goed. Het legt uit waarom een div geen knop is, wat het betekent voor toetsenbordgebruikers, en hoe je het oplost. Dat is meer dan wat axe of Lighthouse je vertellen, die melden alleen dat er een element zonder rol is.

Maar vinden op een live website is een ander verhaal. De DOM doorzoeken werkt als de site onclick-attributen in de HTML heeft staan. Bij JavaScript event listeners (de manier waarop moderne websites klikgedrag koppelen) heb je vuistregels nodig die niet waterdicht zijn.

En dan het punt waar het echt om draait: AI kan je vertellen dat de div een knop moet zijn. Maar het kan niet op Tab drukken. Het leest en redeneert. Het test niet.


Dit is test #1 van de serie “AI en Toegankelijkheidstesten”. Elke test onderzoekt of AI een specifiek toegankelijkheidsprobleem kan detecteren, niet alleen in code maar ook op een live website. Wil je weten hoe toegankelijk jouw website is? Laat het door een mens testen voor het beste resultaat. Neem contact met ons op.

Julia Tol, senior auditor bij Proper Access

Julia Tol, developer, WCAG-expert, AI consultant

Related Posts

Wat is WCAG?

WCAG staat voor Web Content Accessibility Guidelines. Het is de internationale standaard die beschrijft hoe je digitale content toegankelijk maakt voor mensen met een beperking.

Knop zonder naam

Knop zonder naam

“Knop.” Dat is wat een schermlezer zegt. Knop. Maar welke knop? Wat doet die?

Tabellen

Tabellen

Een tabel met openingstijden. Maandag: 09:00 tot 17:00. Visueel snap je direct welke dag bij welke tijd hoort. Maar als die tabel is gebouwd met divjes in plaats van echte table-elementen, ziet een schermlezer alleen losse stukjes tekst. “Maandag.” “09:00 - 17:00.” Zonder de relatie ertussen.