gregorsart
Juli, 2025
Spaß mit Tabellen!
- css
- tabellen
- html
- semantik
- accessibility
Tabellen – nicht gerade der Liebling im Frontend
Kaum jemand arbeitet gern mit ihnen. Direkt nach Formularen stehen sie auf der Beliebtheitsskala ganz unten.
Und ehrlich gesagt: Viel hat sich seit den Anfangstagen des Webs auch nicht getan – sie fühlen sich immer noch ein bisschen nach 1999 an. Warum also nicht einfach auf klassische Tabellen verzichten und stattdessen mit flexibleren <div>-Layouts arbeiten?
Meiner Meinung nach spricht nichts dagegen, vorausgesetzt man hält die Regeln der Accessibility ein. Und wie geht man da nun vor?
Hier einmal eine Tabelle, die nur aus Divs besteht und so einfach wie möglich aufgebaut ist:
<div class="table">
<div class="thead">
<div class="row">
<div class="cell">Name</div>
<div class="cell">Alter</div>
<div class="cell">Stadt</div>
</div>
</div>
<div class="tbody">
<div class="row">
<div class="cell">Anna</div>
<div class="cell">28</div>
<div class="cell">München</div>
</div>
<div class="row">
<div class="cell">Tom</div>
<div class="cell">35</div>
<div class="cell">Hamburg</div>
</div>
</div>
<div class="tfoot">
<div class="row">
<div class="cell span-03">Ich bin die Fußzeile</div>
</div>
</div>
</div> Und hier dieselbe Tabelle, mit ARIA-Rollen und Attributen:
<div class="table" role="table" aria-label="Personenliste">
<div class="thead" role="rowgroup">
<div class="row" role="row">
<div class="cell" role="columnheader" scope="col">Name</div>
<div class="cell" role="columnheader" scope="col">Alter</div>
<div class="cell" role="columnheader" scope="col">Stadt</div>
</div>
</div>
<div class="tbody" role="rowgroup">
<div class="row" role="row">
<div class="cell" role="cell">Anna</div>
<div class="cell" role="cell">28</div>
<div class="cell" role="cell">München</div>
</div>
<div class="row" role="row">
<div class="cell" role="cell">Tom</div>
<div class="cell" role="cell">35</div>
<div class="cell" role="cell">Hamburg</div>
</div>
</div>
<div class="tfoot" role="rowgroup">
<div class="row" role="row">
<div class="cell span-03" role="cell" colspan="3">Ich bin die Fußzeile</div>
</div>
</div>
</div>
Div vs. <table>
Wenn du Barrierefreiheit wirklich optimal umsetzen willst, solltest du ein <table>-Element mit semantisch korrekten HTML-Elementen wie <thead>, <tbody>, <tfoot>, <tr>, <th> und <td> verwenden. Das ist aus Sicht der Zugänglichkeit die beste Wahl, da viele zusätzliche ARIA-Rollen dann gar nicht nötig sind.
Aber:
In meinem Fall brauche ich ein flexibles Tabellengerüst, das sich gut für responsive Layouts und ggf. verschachtelte Tabellenstrukturen eignet. Deshalb habe ich mich für einen HTML-Aufbau mit div-Containern entschieden – kombiniert mit folgendem CSS:
Und dann noch das passende CSS mit dem so flexiblen Grid-Layout & Subgrid:
.table {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
background-color: lightgray;
}
.row,
.thead,
.tbody,
.tfoot {
display: grid;
grid-column: 1 / -1;
grid-template-columns: subgrid;
}
.cell {
display: flex;
justify-content: end;
padding: 1rem;
outline: 1px solid white;
}
.span-03 {
grid-column: span 3;
}
Zwischen-Fazit
Wie bereits erwähnt, sind div-Tabellen aus sich heraus nicht barrierefrei. Ein <div>-Element besitzt keine semantische Bedeutung, weshalb Screenreader und andere assistive Technologien keinerlei strukturelle Information auslesen können – es ist schlicht ein generischer Container. In Bezug auf Semantik und Zugänglichkeit ist div damit die schlechteste Wahl, um komplexe Inhalte wie eine Tabelle korrekt abzubilden.
Auf der anderen Seite wirken native HTML-Tabellen (<table>, <thead>, <tbody>, <tr>, <td>, <th>) in vielen Fällen unflexibel und schwergewichtig – besonders wenn es um responsive Design, fein granular steuerbare Layouts oder verschachtelte Strukturen geht. HTML-Tabellen lassen sich nur schwer in moderne, mobile-first Layouts integrieren und verursachen oft Kopfzerbrechen, sobald man sie an dynamische Inhalte oder CSS-Grids anpassen möchte.
In solchen Fällen ist ein div-basiertes Tabellengerüst zwar ein pragmatischer Kompromiss, aber erfordert deutlich mehr Aufwand, um durch ARIA-Rollen, Fokussteuerung und zusätzliche Screenreader-Hilfen wenigstens ein akzeptables Maß an Barrierefreiheit zu erreichen.
Außerdem noch der Link zu meinem ersten Code-Beispiel auf Codepen.
Verschachtelte Tabellen mit display: contents und Subgrid
Wenn Sie eine Tabelle in einer anderen verschachteln und das gesamte Layout über CSS Grid steuern möchten, ist die Kombination aus display: contents und subgrid die Lösung.
Normalerweise wirkt CSS Grid nur auf direkte Kindelemente. Um die Zellen einer inneren Tabelle vom übergeordneten Grid anordnen zu lassen, müssen alle umschließenden HTML-Elemente aus dem Layout-Fluss genommen werden.
Vorgehensweise:
- Definieren Sie die äußere Tabelle als Grid-Container (display: grid).
- Setzen Sie für alle verschachtelten Tabellenelemente (Tabellenkopf, Tabellenkörper, Tabellenfuß) die Eigenschaft display: contents. Dadurch werden sie für das Layout unsichtbar.
- Die Tabellenzeilen (rows) werden zu Subgrids (display: grid mit grid-template-columns: subgrid). So übernehmen sie die Spaltenstruktur des übergeordneten Grids und können ihre Zellen direkt in diesen Spalten anordnen.
Diese Methode erlaubt es Ihnen, die visuelle Darstellung einer komplexen, verschachtelten Tabellenstruktur mit einem einzigen Grid-Layout zu steuern, ohne die semantisch korrekte HTML-Struktur zu verändern.
Damit man sich das besser vorstellen kann noch der Link zu meinem zweiten Code-Beispiel auf Codepen.