Afbeeldingen toegankelijk maken: alt-teksten en beyond

WCAG praktijk: toegankelijke websites bouwen — stap-voor-stap | wcagtool.nl

WCAG in de praktijk: direct toepasbare oplossingen voor developers en redacties

Toegankelijkheid faalt vaak niet door onwil maar door onduidelijke implementatie: verkeerde ARIA, gebrek aan keyboard-focus, slechte form labels en kleurcontrasten die alleen tijdens ontwerpfase worden gecontroleerd. Dit artikel vertaalt WCAG-normen naar concrete stap-voor-stap code en testbare checks zodat ontwikkelaars, designers en redacties meteen kunnen handelen.

Wij bij wcagtool.nl specialiseren ons in praktische toepassing: voorbeelden die je direct in je codebase plakt, test-scripts die je uitvoert en tools (checker, plugin) die feedback geven. Test je site direct met onze WCAG checker/validator of download onze plugin vanaf de pluginpagina. Vragen? Gebruik ons contactformulier — wij antwoorden binnen 24 uur.

Het probleem in de praktijk

Veelvoorkomende fouten

Ontwikkelaars en redacties maken structurele fouten die tot falende toegankelijkheid leiden. De top 6:

  • Semantiek ontbreekt: divs in plaats van buttons/links.
  • Keyboard interactions: elementen zijn niet bereikbaar of misgedrag bij Enter/Space.
  • Focusmanagement: geen zichtbare focus, focus verdwijnt na modals/dynamische updates.
  • ARIA-misbruik: eigenschappen toegepast zonder semantische ondersteuning.
  • Forms zonder labels of verkeerde foutmeldingen.
  • Kleurcontrast en afbeeldingen zonder alt-tekst.

Waarom dat lastig blijft

Designers leveren kleuren en componenten, developers implementeren snel, redacties vullen content. Zonder concrete handvatten en test-scripts ontstaan inconsistenties. Wij lossen dit op door code-standaarden, checklists en CI-tests die je direct aan je workflow koppelt.

Zo los je dit op in code

1. Gebruik altijd semantische HTML

Stap-voor-stap:

  1. Vervang clickable <div> voor <button> of <a> met href.
  2. Als visueel een link moet lijken: gebruik <a href=”#” role=”button”> alleen wanneer het echt navigatie is; anders <button>.

Voorbeeld: correcte knop

<button type="button" class="btn-primary" aria-pressed="false">Voeg toe</button>

2. Keyboard- en click-compatibiliteit

Regel: native elementen halen keyboard-compatibiliteit al binnen. Gebruik de volgende patronen als je custom elementen bouwt.

<!-- Custom 'button'-achtige div: voeg roles en keyboard handlers toe --><div role="button" tabindex="0" aria-pressed="false" class="custom-btn" onclick="handleClick()" onkeydown="if(event.key==='Enter'||event.key===' ') { event.preventDefault(); handleClick(); }">Actie</div>

3. Focus management en zichtbare focus

CSS focus-styling moet altijd aanwezig zijn en niet uitgezet door resetstyles. Voeg focus-visible toe:

/* Gebruik focus-visible voor browsers die het ondersteunen */.custom-btn:focus{outline:2px solid #005fcc;outline-offset:2px;}@media (prefers-reduced-motion: no-preference){:focus{transition:box-shadow .12s;}}

Wanneer je modals of overlays opent: trap de focus en zet focus terug bij sluiten. Voorbeeld met JavaScript:

// Eenvoudige focus trap (niet productieklaar zonder extra checks)const firstFocusable = modal.querySelector('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])');const focusable = Array.from(modal.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'));const lastFocusable = focusable[focusable.length-1];modal.addEventListener('keydown', (e)=>{ if(e.key==='Tab'){ if(e.shiftKey && document.activeElement===firstFocusable){ e.preventDefault(); lastFocusable.focus(); } else if(!e.shiftKey && document.activeElement===lastFocusable){ e.preventDefault(); firstFocusable.focus(); } } });

4. ARIA correct toepassen

Regel: voeg ARIA alleen toe als native HTML niet volstaat. Gebruik role, aria-labelledby, aria-describedby en aria-live correct.

<!-- Voorbeeld: dynamische foutmelding bij formulier --><div id="error-summary" role="alert" aria-live="assertive">Er is een fout bij het invullen van uw e-mailadres</div>

5. Toegankelijke formulieren

Stap-voor-stap:

  1. Gebruik <label for="id"> gekoppeld aan input met matching id.
  2. Gebruik aria-describedby voor extra instructies.
  3. Toon foutboodschappen inline en in een samenvatting met role=”alert”.
<label for="email">E-mail</label><input id="email" name="email" type="email" aria-describedby="emailHelp error-email" required /><div id="emailHelp">We gebruiken dit om in te loggen</div><div id="error-email" role="alert" aria-live="polite"> </div>

6. Afbeeldingen en alt-teksten

Regels:

  • Decoratieve afbeeldingen: <img alt=”” role=”presentation”>
  • Informatieve afbeeldingen: beschrijf beknopt in alt.
  • Complexe afbeeldingen: geef extra beschrijving naast of via aria-describedby met id naar langere beschrijving.
<img src="grafiek.png" alt="Omzet gestegen van 2019 naar 2024, piek in 2023" /><img src="decoratie.svg" alt="" role="presentation" />

7. Kleurcontrast direct in CSS afdwingen

Gebruik variabelen en controleer in design system. Voorbeelden:

:root{--brand:#005fcc;--text:#1b1b1b;--muted:#666}body{color:var(--text);background:#fff} .btn-primary{background:var(--brand);color:#fff} /* check contrast via tool: tekstkleur op achtergrond moet voldoen aan 4.5:1 voor normale tekst */

Checklist voor developers

Gebruik deze checklist tijdens code review en CI:

  • Semantische tags gebruikt (header, nav, main, footer, button, form)?
  • Alle interactieve elementen focusbaar met tabindex of native elementen?
  • Visible focus-styles aanwezig en consistent?
  • ARIA alleen als ondersteuning, geen vervanging van semantiek?
  • Form labels gekoppeld en foutmeldingen met role=”alert”?
  • Afbeeldingen correct alt-tekst of alt=”” voor decoratie?
  • Kleurcontrast minimaal 4.5:1 voor bodytekst, 3:1 voor grote tekst?
  • Toegankelijkheidschecks in CI met axe-core of onze plugin?

Voor automatische checks in je pipeline: voorbeeld Node script met axe-core

const { AxePuppeteer } = require('axe-puppeteer');const puppeteer = require('puppeteer');(async ()=>{const browser = await puppeteer.launch();const page = await browser.newPage();await page.goto('https://your-site.example');const results = await new AxePuppeteer(page).analyze();console.log(JSON.stringify(results.violations, null, 2));await browser.close();})();

Of: test direct met onze online WCAG checker/validator en voeg de plugin toe voor IDE/browser-integratie: Download plugin. Vragen? Gebruik ons contactformulier — antwoord binnen 24 uur.

Tips voor designers en redacties

Design tokens en kleurkeuze

Werk met design tokens (CSS-variabelen) en zorg dat elke kleurcombinatie automatisch door contrasttests gaat. Voorbeeld workflow:

  1. Definieer tokens in tokens.json of :root.
  2. Gebruik tooling die contrast berekent (CI) en continu checkt.
{ "colors": { "brand": "#005fcc", "text": "#1b1b1b", "muted":"#666" } }

Contentrichtlijnen voor redacties

Concrete regels:

  • Headings: structureer content met H1-H6 in volgorde, nooit skippen.
  • Alt-teksten: korte en begrijpelijke omschrijving; geen “afbeelding van …”.
  • Links: duidelijke linktekst (geen “klik hier”).
  • Formulieren: schrijf heldere fouten met actiegerichte instructie (“Voer een geldig e-mailadres in: example@domein.nl”).

UX-patterns die designers moeten leveren

Lever in component library: focus-states, disabled-states, error-states, aria-attributes voorschriften en voorbeelden met content. Voeg ook microcopy voor screenreaders toe.

Hoe test je dit?

Handmatige tests (snel en effectief)

1) Keyboard-only: verwijder muis en navigeer met Tab/Shift+Tab, Enter en Space. Verwacht: alle interactieve items bereikbaar en logisch volgorden.

2) Screenreader testen: gebruik NVDA (Windows) of VoiceOver (Mac). Check: headings, linkteksten, labels en bij interactieve elementen duidelijke aankondiging van status (aria-pressed, aria-expanded).

NVDA snelle stappen: open NVDA, navigeer met ‘H’ voor headings, ‘K’ voor links, en luister naar error/success announcements.

Automatische tools

Gebruik meerdere tools: axe-core, Lighthouse, en onze WCAG checker/validator. Combineer automatische en handmatige tests omdat tools niet alles detecteren (bv. inhoud van alt-teksten).

// Gebruik axe-core in browserconsole (snel)await axe.run(document).then(results => console.log(results.violations));

Testgevallen die je altijd moet doorlopen

  1. Form validation: onjuiste input tonen van foutmelding en geven van focus naar first error.
  2. Modal open/close: focus trap en terugplaatsen focus naar trigger.
  3. Dynamic content: updates via aria-live voor screenreaders.
  4. Contrast: check alle varianten (hover/active/disabled) met contrasttool.

Test direct je site met onze online checker of installeer de wcagtool plugin in je browser/devtools. Heb je vragen? Gebruik ons contactformulier — antwoord binnen 24 uur.

Extra code-snippets & praktische how-to’s

Skip link implementatie

Voeg een skip link toe voor snelle navigatie:

<a class="skip-link" href="#main-content">Sla navigatie over</a><!-- CSS -->.skip-link{position:absolute;left:-999px;top:auto;width:1px;height:1px;overflow:hidden} .skip-link:focus{position:static;left:0;width:auto;height:auto;padding:8px;background:#000;color:#fff;z-index:1000}

ARIA-live voor dynamische updates

Gebruik aria-live region voor feedback na acties:

<div id="toast" aria-live="polite" aria-atomic="true"></div>function showToast(msg){const toast = document.getElementById('toast');toast.textContent = msg;}

Formulier valideren met focus naar fout

function validate(form){const firstInvalid = form.querySelector(':invalid');if(firstInvalid){firstInvalid.focus();const err = document.getElementById('error-'+firstInvalid.id); if(err){err.textContent = firstInvalid.validationMessage;}}}

Actiegerichte implementatie in 5 minuten

  1. Voer onze WCAG checker uit op je homepage en noteer top 3 violations.
  2. Voeg skip link toe en test keyboard-navigatie (2 minuten).
  3. Kijk naar eerste formulier, voeg ontbrekende <label> toe en role=”alert” voor fouten (5-10 minuten).
  4. Controleer contrast van primaire tekst en knoppen met onze checker (3 minuten).
  5. Installeer de plugin voor snelle lokale checks in je browser.

Blijf niet hangen in perfectie: repareer de grootste problemen eerst en draai daarna regressietests in CI.

Checklist voor QA en deployment

  • Automatische accessibility-scan in CI (axe/puppeteer script).
  • Principe “no tabindex > 0” zonder expliciete reden.
  • Documenteer ARIA-usage in component library.
  • Redactiegids: alt-teksten, linkteksten, headings checklist.
  • Regelmatige audits met wcagtool.nl checker.

Wil je dat wij meekijken? Upload je URL naar onze WCAG checker/validator of vraag een audit via het contactformulier. Antwoord binnen 24 uur.

Laatste praktische tip voor direct gebruik: plak deze korte focus-trap en test met Tab/Shift+Tab — vervang modal met jouw selector.

// Plak en test directconst modal = document.querySelector('#mijn-modal');const focusable = Array.from(modal.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])'));const first = focusable[0];const last = focusable[focusable.length-1];modal.addEventListener('keydown', e => { if(e.key==='Tab'){ if(e.shiftKey && document.activeElement===first){ e.preventDefault(); last.focus(); } else if(!e.shiftKey && document.activeElement===last){ e.preventDefault(); first.focus(); } } });