Toegankelijke tabellen

Ze maken het makkelijk om informatie te vergelijken. Dit werkt alleen als de tabel goed is opgebouwd. Dan kan iedereen de tabel gebruiken, ook mensen met een schermlezer of brailleleesregel.

Correct gebruik van tabellen is dus belangrijk voor toegankelijkheid en gebruiksvriendelijkheid. Dit valt onder succescriterium 1.3.1 Info en relaties.

In dit artikel staan handvatten voor het maken van een toegankelijke tabel.

Wanneer gebruik je een tabel?

Gebruik een tabel alleen voor gegevens die een logisch verband hebben in twee richtingen: rijen én kolommen. Vraag jezelf af: heeft deze informatie koppen nodig om de gegevens te begrijpen? Als het antwoord ja is, dan is een tabel de juiste keuze.

Gebruik een tabel niet om content op een bepaalde manier op te maken. Zo’n tabel heet een presentatietabel. Presentatietabellen werden vroegen nog wel eens gebruikt maar zijn tegenwoorden echt niet meer nodig. Gebruik in plaats daarvan CSS (zoals Flexbox of Grid) voor de opmaak van de pagina.

Een presentatietabel is verwarrend voor schermlezers. De schermlezer verwacht gegevens met tabelkoppen, maar die zijn er niet. Als er toch een oude presentatietabel in de code staat, voeg dan role="presentation" toe aan het <table>-element. Dit vertelt de schermlezer dat het geen datatabel is. Gebruik in een presentatietabel geen <th>-, <caption>– of scope-elementen.

Tabellen gebruiken

Een tabel kan in een CMS meestal makkelijk worden toegevoegd in de editor op de pagina. Geef aan welke cellen tabelkoppen zijn en in welke cellen gegevens staan.

Houd tabellen zo eenvoudig mogelijk. Gebruik bij voorkeur één rij met kolomkoppen of één kolom met rijkoppen. Vermijd het samenvoegen van cellen. Is de tabel te complex? Splits de tabel dan op in twee of meer eenvoudige tabellen.

Hoe schermlezers tabellen verwerken

Een schermlezer herkent een tabel aan de HTML-code. Bij het bereiken van een tabel kondigt de schermlezer het aantal rijen en kolommen aan. Daarna kan de gebruiker van cel naar cel navigeren met sneltoetsen. Bij elke cel leest de schermlezer de bijbehorende tabelkop voor.

Stel, je hebt een tabel met productnamen in de eerste kolom en prijzen in de tweede kolom. Als iemand naar de cel met “€ 24,95” navigeert, leest de schermlezer: “Prijs, € 24,95”. Zonder de juiste tabelkoppen in de code leest de schermlezer alleen “€ 24,95”. De gebruiker weet dan niet bij welk product die prijs hoort.

Dit is precies waarom de juiste code zo belangrijk is. Zonder <th>-elementen kan een schermlezer geen verband leggen tussen de tabelkoppen en de gegevenscellen.

Code voor tabellen

Tabellen worden in de code opgemaakt met het <table>-element. Dit element heeft onderliggende <tr>-, <th>-, en <td>-elementen:

  • Het <tr>-element wordt gebruikt voor een tabelrij.
  • Het <th>-element wordt gebruikt voor een tabelkop.
  • Gegevenscellen worden opgemaakt met <td>-elementen.

Het <caption>-element geeft een korte beschrijving van de inhoud van de tabel. Het is het eerste element binnen <table>. Een schermlezer leest het bijschrift voor bij het aankondigen van de tabel. Zo weet de gebruiker meteen wat voor informatie de tabel bevat.

<table>
  <caption>Openingstijden per vestiging</caption>
  ...
</table>

Let op: het summary-attribuut op het <table>-element is verouderd in HTML5. Gebruik het niet meer.

Eenvoudige tabellen

In eenvoudige tabellen kan hulptechnologie de relaties tussen koppen en gegevens vaak zelf bepalen. Gebruik de juiste HTML-elementen voor tabelkoppen (<th>) en gegevenscellen (<td>).

Voorbeeld van een tabel met één rij met kolomkoppen:

<table>
  <caption>Openingstijden per vestiging</caption>
  <tr>
    <th>Vestiging</th>
    <th>Maandag</th>
    <th>Dinsdag</th>
  </tr>
  <tr>
    <td>Amsterdam</td>
    <td>09:00 – 17:00</td>
    <td>09:00 – 17:00</td>
  </tr>
  <tr>
    <td>Rotterdam</td>
    <td>10:00 – 18:00</td>
    <td>10:00 – 18:00</td>
  </tr>
</table>

Voorbeeld van een tabel met één kolom met rijkoppen:

<table>
  <caption>Contactgegevens</caption>
  <tr>
    <th>Telefoon</th>
    <td>+31 314 00 00 00</td>
  </tr>
  <tr>
    <th>E-mail</th>
    <td>info@voorbeeld.nl</td>
  </tr>
</table>

Complexe tabellen

Sommige tabellen hebben koppen in twee richtingen: zowel in de rijen als in de kolommen. In die gevallen moet je in de code aangeven welke kop bij welke cellen hoort. Dit doe je met het scope-attribuut.

Voeg scope="col" toe aan kolomkoppen en scope="row" aan rijkoppen.

Voorbeeld van een tabel met kolomkoppen én rijkoppen en het scope-attribuut:

<table>
  <caption>Openingstijden per vestiging</caption>
  <tr>
    <td></td>
    <th scope="col">Maandag</th>
    <th scope="col">Dinsdag</th>
  </tr>
  <tr>
    <th scope="row">Amsterdam</th>
    <td>09:00 – 17:00</td>
    <td>09:00 – 17:00</td>
  </tr>
  <tr>
    <th scope="row">Rotterdam</th>
    <td>10:00 – 18:00</td>
    <td>10:00 – 18:00</td>
  </tr>
</table>

De lege cel linksboven is een <td>, geen <th>. Deze cel heeft geen functie als tabelkop.

Het headers-attribuut

Voor tabellen met koppen die meerdere rijen of kolommen overspannen, kun je het headers-attribuut gebruiken. Dit attribuut koppelt een gegevenscel aan een of meer tabelkoppen via het id-attribuut.

Let op: Het headers-attribuut wordt niet breed ondersteund door schermlezers.

Voorbeeld van een tabel met kolomkoppen én rijkoppen en het headers-attribuut:

<table>
  <caption>Omzet per kwartaal</caption>
  <tr>
    <td></td>
    <th id="q1">Q1</th>
    <th id="q2">Q2</th>
  </tr>
  <tr>
    <th id="amsterdam">Amsterdam</th>
    <td headers="amsterdam q1">€ 150.000</td>
    <td headers="amsterdam q2">€ 175.000</td>
  </tr>
</table>

Nog complexere tabellen

Het is mogelijk om tabellen te gebruiken met koppen voor meerdere rijen en kolommen. Gebruik hiervoor de <thead>-, <tbody>– en <tfoot>-elementen om de tabel te structureren en de scope-waarden colgroup en rowgroup om de koppen te koppelen.

  • Het <thead>-element bevat de rijen met kolomkoppen.
  • Het <tbody>-element bevat de rijen met gegevenscellen.
  • Het <tfoot>-element bevat de rij met totalen of samenvattingen.
<table>
  <caption>Omzet per kwartaal per regio</caption>
  <thead>
    <tr>
      <td rowspan="2"></td>
      <th colspan="2" scope="colgroup">Noord</th>
      <th colspan="2" scope="colgroup">Zuid</th>
    </tr>
    <tr>
      <th scope="col">Q1</th>
      <th scope="col">Q2</th>
      <th scope="col">Q1</th>
      <th scope="col">Q2</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th scope="row">Omzet</th>
      <td>€ 50.000</td>
      <td>€ 60.000</td>
      <td>€ 45.000</td>
      <td>€ 55.000</td>
    </tr>
    <tr>
      <th scope="row">Kosten</th>
      <td>€ 30.000</td>
      <td>€ 35.000</td>
      <td>€ 25.000</td>
      <td>€ 28.000</td>
    </tr>
  </tbody>
  <tfoot>
    <tr>
      <th scope="row">Winst</th>
      <td>€ 20.000</td>
      <td>€ 25.000</td>
      <td>€ 20.000</td>
      <td>€ 27.000</td>
    </tr>
  </tfoot>
</table>

Let op: <thead>, <tbody> en <tfoot> geven op zichzelf geen extra informatie aan een schermlezer. Ze zijn wel nuttig om stijlkenmerken toe te voegen aan onderdelen van de tabel en om de code leesbaar te houden.

Pas op met te complexe tabellen. Met te veel informatie in één tabel wordt het onoverzichtelijk. Kies dan liever voor twee of meer eenvoudige tabellen.

Lege cellen

Laat cellen niet leeg. Een lege cel kan verwarrend zijn, omdat een schermlezer dan alleen de positie aankondigt zonder inhoud. Vul lege cellen met een passende tekst, zoals “N.v.t.” (niet van toepassing), “Geen”, “0” of een streepje (–). Gebruik bij een streepje visueel verborgen tekst zodat een schermlezer de betekenis kan presenteren.

<td><span class="sr-only">Niet van toepassing</span>–</td>

De uitzondering is de lege cel linksboven in een tabel met zowel kolom- als rijkoppen. Die cel mag wél leeg zijn. Gebruik hiervoor een <td>-element, geen <th>.

Grote tabellen

Soms past een tabel niet volledig op het scherm. Voeg in dat geval een horizontale scroll toe, zodat bezoekers de tabel kunnen scrollen. Gebruik hiervoor een container rond de tabel met overflow-x: auto.

Zorg dan ook dat de horizontale scroll van de tabel met het toetsenbord te bereiken en bedienen is. Dit wordt gedaan met het tabindex-attribuut.

<div style="overflow-x:auto;" tabindex="0">
  <table>
    ...
  </table>
</div>

Let op: sommige responsieve technieken gebruiken CSS om tabelrijen onder elkaar te stapelen op kleine schermen (bijvoorbeeld met display: block). Dit kan de tabelstructuur voor schermlezers breken. De relaties tussen koppen en gegevenscellen gaan dan verloren. Horizontaal scrollen is een veiliger oplossing die de tabelstructuur intact laat.

Vereisten en aanbevelingen voor toegankelijke tabellen

Dit zijn de vereisten en aanbevelingen voor het maken van toegankelijke tabellen:

WCAG-vereisten

  • Gebruik het <th>-element voor tabelkoppen en het <td>-element voor gegevenscellen.
  • Gebruik het scope-attribuut als de tabel koppen in twee richtingen heeft.
  • Gebruik geen tabelopmaak (<th>, <caption>, scope) in presentatietabellen.

Aanbevolen

  • Geef elke tabel een <caption>-element met een korte beschrijving.
  • Houd tabellen zo eenvoudig mogelijk.
  • Vermijd het samenvoegen van cellen.
  • Splits complexe tabellen op in meerdere eenvoudige tabellen.
  • Laat cellen niet leeg. Gebruik “N.v.t.”, “Geen” of “0”.
  • Maak grote tabellen horizontaal scrollbaar in een container met role="region" en tabindex="0".
  • Vermijd geneste tabellen.

Gerelateerde WCAG succescriteria

Dit artikel behandelt het WCAG-succescriterium 1.3.1 Info en relaties (niveau A).