Barrierefreie Komponenten · Medien
Komplexe Datentabellen barrierefrei
Eine einfache Tabelle ist barrierefrei schnell erledigt: <th> mit scope für die Kopfzellen, ein <caption> als Überschrift, fertig. Die Grundlagen dazu behandelt Tabellen semantisch aufbauen. Schwierig wird es erst, wenn eine Tabelle zwei Dimensionen hat – wenn also jede Datenzelle von einer Zeilen- und einer Spaltenüberschrift abhängt, vielleicht noch mit gruppierten oder mehrstufigen Köpfen. Dann reicht scope allein manchmal nicht.
Vorweg meine ehrlichste Empfehlung: Die beste komplexe Tabelle ist eine, die du vereinfachen konntest. Lässt sich eine große Kreuztabelle in zwei kleinere aufteilen, ist das fast immer die zugänglichere Lösung. Erst wenn die Komplexität wirklich im Inhalt steckt, kommen die folgenden Techniken zum Einsatz.
scope für gruppierte Köpfe
Solange die Struktur klar ist, trägt scope weit – auch über einfache Zeilen- und Spaltenköpfe hinaus. Mit scope="colgroup" und scope="rowgroup" lassen sich übergeordnete Köpfe kennzeichnen, die für eine ganze Gruppe gelten:
<table>
<caption>Umsatz nach Quartal und Region</caption>
<tr>
<td></td>
<th scope="colgroup" colspan="2">2025</th>
<th scope="colgroup" colspan="2">2026</th>
</tr>
<tr>
<td></td>
<th scope="col">Q1</th><th scope="col">Q2</th>
<th scope="col">Q1</th><th scope="col">Q2</th>
</tr>
<tr>
<th scope="row">Nord</th>
<td>120</td><td>135</td><td>128</td><td>140</td>
</tr>
</table>
Für viele zweidimensionale Tabellen ist das schon ausreichend und angenehm wartbar.
headers und id für echte Mehrdimensionalität
Reicht scope nicht mehr aus – etwa weil Köpfe unregelmäßig verteilt sind –, kommt die explizite Variante: Jede Kopfzelle bekommt eine id, und jede Datenzelle verweist per headers auf alle Köpfe, die sie beschreiben. Das ist mehr Schreibarbeit, dafür aber völlig eindeutig:
<table>
<caption>Öffnungszeiten nach Standort</caption>
<thead>
<tr>
<td></td>
<th id="mo" scope="col">Montag</th>
<th id="di" scope="col">Dienstag</th>
</tr>
</thead>
<tbody>
<tr>
<th id="berlin" scope="row">Berlin</th>
<td headers="berlin mo">9–18 Uhr</td>
<td headers="berlin di">9–18 Uhr</td>
</tr>
<tr>
<th id="hamburg" scope="row">Hamburg</th>
<td headers="hamburg mo">10–16 Uhr</td>
<td headers="hamburg di">geschlossen</td>
</tr>
</tbody>
</table>
Ein Screenreader liest die Zelle „geschlossen“ jetzt als „Hamburg, Dienstag, geschlossen“ – mit vollem Kontext, egal wo im Tabellengewirr man landet. Genau dafür ist headers/id da: Es macht die Zugehörigkeit ausdrücklich, statt sie aus der Position erraten zu lassen.
Den Zweck der Tabelle benennen
Jede Datentabelle sollte ein <caption> haben – es ist die Überschrift der Tabelle und das Erste, was ein Screenreader ankündigt. Bei komplexen Tabellen hilft zusätzlich ein kurzer erklärender Satz davor oder daneben, der die Struktur in Worte fasst („Zeilen: Standorte, Spalten: Wochentage“). Das nimmt der reinen Tabellennavigation die Orientierungslast.
Häufige Fehler
- Tabellen fürs Layout. Tabellen sind für Daten, nicht für Seitenraster – ein Erbe, das ich aus den frühen 2000ern nun wirklich nicht zurückhaben möchte.
-
Datenzellen als
<td>ohne Köpfe. Ohne<th>mitscope(oderheaders) fehlt der Bezug komplett. -
headerszeigt auf falsche oder fehlendeid. Die Verweise müssen exakt stimmen, sonst stiftet die Technik mehr Verwirrung als Nutzen. - Verschachtelte Tabellen. Eine Tabelle in der Tabelle ist für Screenreader kaum zu durchschauen – fast immer ein Zeichen, dass man vereinfachen sollte.
-
Kein
<caption>. Die Tabelle bleibt namenlos.
Häufige Fragen
scope oder headers/id – was nehme ich?
scope, solange die Struktur regelmäßig ist – es ist kürzer und besser wartbar. headers/id erst, wenn die Köpfe so verteilt sind, dass scope sie nicht mehr eindeutig zuordnen kann. Beides zu mischen, stiftet eher Verwirrung.
Wie gehe ich mit sehr breiten Tabellen auf dem Smartphone um?
Lass die Tabelle eine Tabelle bleiben und mache den Bereich horizontal scrollbar (ein Container mit overflow-x:auto), statt die Struktur per CSS aufzubrechen. Letzteres zerstört leicht die Zuordnung von Kopf und Zelle.
Gehören Diagramme auch hierher?
Ein Diagramm ist ein Bild – es braucht eine Textalternative. Oft ist die beste Alternative genau die zugrunde liegende Datentabelle direkt daneben. So bekommt jede und jeder die Zahlen, egal ob die Grafik wahrnehmbar ist.
Fazit
Komplexe Tabellen werden zugänglich, indem jede Datenzelle ihre Köpfe kennt: über scope (auch colgroup/rowgroup) bei regelmäßiger Struktur, über headers/id bei echter Mehrdimensionalität – immer mit einem benennenden <caption>. Die wirkungsvollste Maßnahme bleibt aber, die Tabelle so einfach zu halten, wie der Inhalt es zulässt.