Komponenten · Medien & Daten
Sortierbare & filterbare Tabellen barrierefrei
Sobald eine Tabelle sortier- und filterbar wird, kommen zur soliden Tabellen-Semantik drei neue Fragen dazu: Wie bedient man die Sortierung ohne Maus? Woher weiß ein Screenreader, wonach gerade sortiert ist? Und wer sagt Bescheid, wenn der Filter die Liste umbaut? Für alle drei gibt es etablierte Antworten – das Sortable-Table-Muster aus dem ARIA Authoring Practices Guide (APG) plus eine Live-Region.
Die Basis: eine echte Tabelle
Ohne Fundament kein Muster: <table> mit <caption>, <th scope="col"> für Spaltenköpfe – alles wie in
Tabellen semantisch aufbauen
beschrieben (WCAG 1.3.1). Ein div-Grid mit Tabellen-Optik disqualifiziert sich hier von selbst: Es verliert die Zellen-Navigation, mit der Screenreader-Nutzer Tabellen erkunden.
Sortierung: Button im Kopf, Zustand am Kopf
<table>
<caption>Offene Rechnungen</caption>
<thead>
<tr>
<th scope="col" aria-sort="ascending">
<button type="button">
Fälligkeit
<span aria-hidden="true">▲</span>
</button>
</th>
<th scope="col" aria-sort="none">
<button type="button">Betrag</button>
</th>
</tr>
</thead>
<tbody>…</tbody>
</table>
Die Regeln dahinter:
-
Der Auslöser ist ein
<button>im<th>– nicht der<th>selbst mit Klick-Handler. Nur so gibt es Fokus, Enter und Leertaste gratis (Buttons vs. Links). -
aria-sortsitzt am<th>(nicht am Button) und kenntascending,descending,none. Immer nur eine Spalte trägt einen aktiven Wert. Screenreader sagen dann „Fälligkeit, aufsteigend sortiert, Spaltenkopf“ an – das erfüllt 4.1.2 Name, Rolle, Wert. - Der Pfeil ist Deko (
aria-hidden="true") – die Information trägtaria-sort. Und der Pfeil allein wäre zu wenig: Richtung nur über ein Symbol ohne Zustands-Attribut scheitert an 1.3.1; zusätzlich braucht das Icon 3:1 Kontrast.
Nach dem Umsortieren bleibt der Fokus auf dem geklickten Button – kein Sprung, kein Neuladen-Gefühl (2.4.3).
Filter: ein Formular wie jedes andere – plus Ansage
Filter sind Formulare: sichtbare Labels, Gruppen in fieldset/legend, und kein Kontextwechsel beim Auswählen (3.2.2) – die Trefferliste darf sich daneben aktualisieren, aber nichts darf den Fokus stehlen oder die Seite wechseln.
Das Ergebnis braucht eine Statusmeldung (4.1.3):
<p role="status" id="treffer-status">
17 Rechnungen gefunden, gefiltert nach „offen“.
</p>
Die Live-Region existiert von Anfang an im DOM; das Skript schreibt nach jedem Filter- oder Sortierlauf den neuen Text hinein. Sichtbar anzeigen schadet nie – die Trefferzahl hilft allen.
Randnotiz – Reflow nicht vergessen. Breite Datentabellen sind die legitime Ausnahme der Reflow-Regel: Sie dürfen im eigenen Container horizontal scrollen (
overflow-x: autoplustabindex="0"und Beschriftung am Scroll-Container, damit auch Tastaturnutzer scrollen können). Die Seite drumherum muss trotzdem umbrechen.
Häufige Fehler
-
Klick-Handler direkt auf
<th>– ohne Button keine Tastatur. -
aria-sortfehlt oder klebt auf allen Spalten gleichzeitig. - Lautlose Updates – die Liste ändert sich, niemand erfährt es (4.1.3).
- Filter löst Seiten-Reload aus und wirft den Fokus an den Anfang.
- Nur-Icon-Sortierpfeile ohne Namen und Zustand.
- CSS-Grid-Pseudotabelle – Semantik weg, Navigation weg.
Häufige Fragen
Muss die Sortierung auch ohne JavaScript funktionieren?
Ideal ist ein Fallback über echte Links (?sort=betrag) mit Server-Sortierung – robust und SEO-freundlich. Wo das nicht geht, gilt: Die JS-Variante muss vollständig tastatur- und screenreader-tauglich sein; ein Zero-JS-Zwang folgt aus den WCAG nicht.
Wie kündige ich die Sortier-Funktion an?
Der Button-im-Kopf macht sie entdeckbar; zusätzlich hilft ein Satz in der <caption> oder davor („Spalten lassen sich per Klick auf die Überschrift sortieren“). Wichtiger als die Ankündigung ist der korrekte Zustand via aria-sort.
Und richtig große Tabellen mit Paginierung?
Dann kommt das Muster Pagination & „Mehr laden“ dazu – inklusive Fokus-Management beim Nachladen. Für mehrdimensionale Monster gilt zuerst komplexe Datentabellen.
Fazit
Sortierbare Tabellen sind drei Zutaten: echte Tabellen-Semantik, ein <button> im Spaltenkopf mit aria-sort am <th>, und eine Live-Region, die Filter- und Sortier-Ergebnisse ansagt. Damit sind Tastatur, Zustand und Statusmeldung abgedeckt – und die Daten selbst gehören, wenn sie visualisiert werden, in barrierefreie Diagramme.