Tabellen mit CSS gestalten
HTML legt die Struktur und Bedeutung einer Tabelle fest. Das sichtbare Erscheinungsbild
wird anschließend mit CSS gestaltet. Dazu gehören beispielsweise Tabellenbreite,
Rahmen, Innenabstände, Farben und die Ausrichtung der Zellinhalte.
Grundgestaltung einer Tabelle
Ohne eigene CSS-Regeln stellt der Browser eine Tabelle nur sehr schlicht dar. Mit
wenigen Eigenschaften kann sie übersichtlicher und besser lesbar gestaltet werden.
<table class="preisliste">
<caption>Preisliste für Computerzubehör</caption>
<thead>
<tr>
<th scope="col">Produkt</th>
<th scope="col">Anzahl</th>
<th scope="col">Preis</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Tastatur</th>
<td>2</td>
<td>49,90 €</td>
</tr>
<tr>
<th scope="row">Maus</th>
<td>3</td>
<td>24,90 €</td>
</tr>
</tbody>
</table>
.preisliste {
width: 100%;
border-collapse: collapse;
}
.preisliste th,
.preisliste td {
padding: 0.75rem;
border: 1px solid #adb5bd;
text-align: left;
}
Die Tabelle nimmt die verfügbare Breite ihres übergeordneten Elements ein. Die
Tabellenzellen erhalten einen Innenabstand und einen sichtbaren Rahmen.
Rahmenmodell von Tabellen
Standardmäßig besitzt jede Tabellenzelle einen eigenen Rahmen. Dadurch kann zwischen
benachbarten Zellen ein Zwischenraum oder ein doppelter Rahmen entstehen.
| Eigenschaft |
Wert |
Wirkung |
border-collapse |
separate |
Jede Zelle besitzt einen eigenen Rahmen; Standardwert |
border-collapse |
collapse |
Benachbarte Zellrahmen werden zu einem gemeinsamen Rahmen verbunden |
border-spacing |
Längenangabe |
Bestimmt den Abstand zwischen getrennten Zellrahmen |
table {
border-collapse: collapse;
}
Für gewöhnliche Datentabellen wird häufig
border-collapse: collapse verwendet.
table {
border-collapse: separate;
border-spacing: 0.5rem;
}
border-spacing wirkt nur, wenn die Rahmen mit
border-collapse: separate getrennt bleiben.
Tabellenkopf gestalten
Der Tabellenkopf kann durch eine Hintergrundfarbe deutlich vom Datenbereich
abgesetzt werden.
.preisliste thead {
background-color: #343a40;
color: #fff;
}
.preisliste thead th {
font-weight: 600;
}
Eine ausreichende Farbdifferenz zwischen Text und Hintergrund ist besonders wichtig.
Farbe sollte außerdem nicht das einzige Mittel sein, mit dem unterschiedliche
Tabellenbereiche gekennzeichnet werden.
Wechselnde Zeilenfarben
Bei Tabellen mit vielen Datensätzen können wechselnde Hintergrundfarben das Verfolgen
einer Zeile erleichtern. Dafür eignet sich die Pseudoklasse
:nth-child().
.preisliste tbody tr:nth-child(even) {
background-color: #f2f2f2;
}
Mit even werden die geraden Zeilen ausgewählt. Für ungerade Zeilen kann
der Wert odd verwendet werden.
.preisliste tbody tr:nth-child(odd) {
background-color: #fff;
}
.preisliste tbody tr:nth-child(even) {
background-color: #f2f2f2;
}
Zeilen beim Überfahren hervorheben
Eine Datenzeile kann hervorgehoben werden, wenn der Mauszeiger darüber bewegt wird.
Dadurch lässt sich eine umfangreiche Tabelle leichter lesen.
.preisliste tbody tr:hover {
background-color: #dbeafe;
}
Wichtig:
Eine Gestaltung mit :hover ist auf Geräten mit Touchscreen nicht
zuverlässig verfügbar. Wichtige Informationen dürfen deshalb nicht ausschließlich
beim Überfahren mit der Maus sichtbar werden.
Zellinhalte ausrichten
Texte werden üblicherweise linksbündig dargestellt. Zahlen und Geldbeträge sind
dagegen oft leichter vergleichbar, wenn sie rechtsbündig ausgerichtet werden.
.preisliste th {
text-align: left;
}
.preisliste td:nth-child(2) {
text-align: center;
}
.preisliste th:last-child,
.preisliste td:last-child {
text-align: right;
}
Mit :nth-child(2) wird die zweite Zelle jeder Zeile ausgewählt.
:last-child wählt jeweils die letzte Zelle einer Zeile aus.
Hinweis:
Die Auswahl über die Position einer Zelle ist für einfache Tabellen geeignet. Bei
komplexeren Tabellen können aussagekräftige Klassen leichter verständlich und
wartbar sein.
<td class="anzahl">2</td>
<td class="preis">49,90 €</td>
.anzahl {
text-align: center;
}
.preis {
text-align: right;
white-space: nowrap;
}
Tabellenbeschriftung gestalten
Auch die mit <caption> erstellte Tabellenbeschriftung kann mit CSS
gestaltet und positioniert werden.
.preisliste caption {
padding: 0.75rem;
font-size: 1.25rem;
font-weight: bold;
text-align: left;
caption-side: top;
}
| Wert |
Wirkung |
caption-side: top |
Die Beschriftung wird oberhalb der Tabelle angezeigt |
caption-side: bottom |
Die Beschriftung wird unterhalb der Tabelle angezeigt |
Die Tabellenbeschriftung sollte den Inhalt oder Zweck der Tabelle kurz und eindeutig
beschreiben.
Vollständige Tabellengestaltung
.preisliste {
width: 100%;
border-collapse: collapse;
color: #343a40;
}
.preisliste caption {
padding: 0.75rem;
font-size: 1.25rem;
font-weight: bold;
text-align: left;
caption-side: top;
}
.preisliste th,
.preisliste td {
padding: 0.75rem;
border: 1px solid #adb5bd;
text-align: left;
}
.preisliste thead {
background-color: #343a40;
color: #fff;
}
.preisliste tbody tr:nth-child(even) {
background-color: #f2f2f2;
}
.preisliste tbody tr:hover {
background-color: #dbeafe;
}
.preisliste td:nth-child(2) {
text-align: center;
}
.preisliste th:last-child,
.preisliste td:last-child {
text-align: right;
white-space: nowrap;
}
Dieses Beispiel gestaltet nur die Darstellung der Tabelle. Die semantische
HTML-Struktur mit <caption>,
<thead>, <tbody>,
<th> und scope bleibt weiterhin entscheidend.
Responsive Tabellen
Tabellen benötigen häufig mehr Breite, als auf einem kleinen Bildschirm verfügbar ist.
Ohne besondere Maßnahmen können Spalten abgeschnitten werden oder die gesamte Webseite
verbreitern. Deshalb muss für umfangreiche Tabellen eine passende responsive Darstellung
vorgesehen werden.
Das Problem auf kleinen Bildschirmen
Eine Tabelle versucht normalerweise, alle Spalten innerhalb der verfügbaren Breite
darzustellen. Bei vielen Spalten oder langen Zellinhalten kann das zu sehr schmalen
Spalten, unleserlichen Zeilenumbrüchen oder horizontalem Überlauf führen.
<table class="preisliste">
<thead>
<tr>
<th scope="col">Artikelnummer</th>
<th scope="col">Produktbezeichnung</th>
<th scope="col">Kategorie</th>
<th scope="col">Lagerbestand</th>
<th scope="col">Einzelpreis</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">EDV-1001</th>
<td>Mechanische Tastatur</td>
<td>Eingabegeräte</td>
<td>24 Stück</td>
<td>89,90 €</td>
</tr>
</tbody>
</table>
Wichtig:
Eine Tabelle sollte nicht allein durch sehr kleine Schrift oder stark verkleinerte
Zellabstände an einen schmalen Bildschirm angepasst werden. Die Inhalte müssen weiterhin
gut lesbar und bedienbar bleiben.
Horizontal scrollbare Tabelle
Die einfachste und meistens zuverlässigste Lösung besteht darin, die Tabelle in ein
zusätzliches Element einzuschließen. Dieses Element erhält bei Bedarf eine horizontale
Bildlaufleiste.
<div class="table-scroll">
<table class="preisliste">
<caption>Lagerbestand für Computerzubehör</caption>
<thead>
<tr>
<th scope="col">Artikelnummer</th>
<th scope="col">Produkt</th>
<th scope="col">Kategorie</th>
<th scope="col">Bestand</th>
<th scope="col">Preis</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">EDV-1001</th>
<td>Mechanische Tastatur</td>
<td>Eingabegeräte</td>
<td>24 Stück</td>
<td>89,90 €</td>
</tr>
<tr>
<th scope="row">EDV-1002</th>
<td>Kabellose Maus</td>
<td>Eingabegeräte</td>
<td>38 Stück</td>
<td>39,90 €</td>
</tr>
</tbody>
</table>
</div>
.table-scroll {
max-width: 100%;
overflow-x: auto;
}
.preisliste {
width: 100%;
min-width: 700px;
border-collapse: collapse;
}
Solange genügend Platz vorhanden ist, füllt die Tabelle mit
width: 100% ihren Container aus. Auf schmaleren Bildschirmen verhindert
min-width, dass die Spalten zu stark zusammengedrückt werden. Der
überstehende Tabellenbereich kann innerhalb von .table-scroll horizontal
verschoben werden.
Hinweis:
overflow-x: auto sollte auf das umschließende Element und nicht direkt auf
<table> angewendet werden.
Scrollbereich für die Tastaturbedienung
Ein horizontaler Scrollbereich sollte nicht nur mit Maus oder Touchscreen bedienbar sein.
Mit tabindex="0" kann das umschließende Element über die Tastatur fokussiert
werden.
<div
class="table-scroll"
tabindex="0"
role="region"
aria-label="Lagerbestand für Computerzubehör"
>
<table class="preisliste">
...
</table>
</div>
.table-scroll:focus {
outline: 3px solid #0d6efd;
outline-offset: 2px;
}
Das Element erhält einen zugänglichen Namen und einen deutlich sichtbaren Fokusrahmen.
Sobald der Scrollbereich fokussiert ist, kann er abhängig vom Browser und Betriebssystem
mit den Pfeiltasten horizontal verschoben werden.
Wichtig:
Ein vorhandener Fokusrahmen darf nicht ohne gleichwertigen Ersatz entfernt werden. Er
zeigt Tastaturbenutzern, welches Element gerade aktiv ist.
Scrollhinweis anzeigen
Auf einem Touchscreen ist eine horizontale Bildlaufleiste nicht immer dauerhaft sichtbar.
Ein kurzer Hinweis vor der Tabelle kann deutlich machen, dass weitere Spalten durch
seitliches Verschieben erreichbar sind.
<p class="scroll-hinweis">
Auf kleinen Bildschirmen kann die Tabelle seitlich verschoben werden.
</p>
<div
class="table-scroll"
tabindex="0"
role="region"
aria-label="Lagerbestand für Computerzubehör"
>
<table class="preisliste">
...
</table>
</div>
.scroll-hinweis {
display: none;
}
@media (max-width: 767.98px) {
.scroll-hinweis {
display: block;
font-size: 0.9rem;
}
}
Der Hinweis wird nur auf kleineren Bildschirmen eingeblendet. Die Tabelle selbst und ihre
semantische Struktur bleiben dabei unverändert.
Responsive Tabelle mit Bootstrap
Bootstrap stellt mit .table-responsive bereits einen passenden
Scroll-Container zur Verfügung. Die Klasse wird auf ein Element gesetzt, das die
eigentliche Tabelle umschließt.
<div class="table-responsive">
<table class="table table-striped table-bordered align-middle">
<caption>Lagerbestand für Computerzubehör</caption>
<thead class="table-dark">
<tr>
<th scope="col">Artikelnummer</th>
<th scope="col">Produkt</th>
<th scope="col">Kategorie</th>
<th scope="col">Bestand</th>
<th scope="col">Preis</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">EDV-1001</th>
<td>Mechanische Tastatur</td>
<td>Eingabegeräte</td>
<td>24 Stück</td>
<td>89,90 €</td>
</tr>
<tr>
<th scope="row">EDV-1002</th>
<td>Kabellose Maus</td>
<td>Eingabegeräte</td>
<td>38 Stück</td>
<td>39,90 €</td>
</tr>
</tbody>
</table>
</div>
Die Tabelle behält ihre normale Tabellenstruktur. Falls sie breiter als das
umschließende Element wird, stellt Bootstrap innerhalb des Containers horizontales
Scrollen bereit.
Merke:
.table-responsive gehört um die Tabelle.
.table, .table-striped und weitere Tabellenklassen gehören
direkt auf das <table>-Element.
Responsive Bootstrap-Breakpoints
Bootstrap bietet zusätzlich responsive Varianten an. Damit wird die Tabelle nur
unterhalb eines bestimmten Breakpoints horizontal scrollbar.
| Klasse |
Horizontal scrollbar |
.table-responsive |
Bei Bedarf auf allen Bildschirmgrößen |
.table-responsive-sm |
Unterhalb von 576 px |
.table-responsive-md |
Unterhalb von 768 px |
.table-responsive-lg |
Unterhalb von 992 px |
.table-responsive-xl |
Unterhalb von 1200 px |
.table-responsive-xxl |
Unterhalb von 1400 px |
<div class="table-responsive-md">
<table class="table">
...
</table>
</div>
In diesem Beispiel wird die Tabelle auf Geräten unterhalb des
md-Breakpoints horizontal scrollbar. Ab 768 px wird sie wieder wie
eine gewöhnliche Tabelle dargestellt.
Spalteninhalte sinnvoll umbrechen
Nicht jeder Inhalt sollte auf dieselbe Weise umgebrochen werden. Beschreibungen dürfen
meist mehrere Zeilen beanspruchen. Artikelnummern, Datumsangaben oder Geldbeträge sollten
dagegen häufig zusammenbleiben.
.preisliste .beschreibung {
min-width: 16rem;
overflow-wrap: break-word;
}
.preisliste .artikelnummer,
.preisliste .datum,
.preisliste .preis {
white-space: nowrap;
}
<th class="artikelnummer" scope="row">EDV-1001</th>
<td class="beschreibung">Mechanische Tastatur mit Beleuchtung</td>
<td class="datum">25.07.2026</td>
<td class="preis">89,90 €</td>
white-space: nowrap verhindert einen Zeilenumbruch innerhalb des Elements.
Die Eigenschaft sollte gezielt eingesetzt werden, da sie die benötigte Tabellenbreite
vergrößern kann.
Spalten nicht einfach ausblenden
Gelegentlich werden auf kleinen Bildschirmen einzelne Spalten mit
display: none ausgeblendet. Dadurch können jedoch wichtige Informationen
verloren gehen.
@media (max-width: 767.98px) {
.preisliste .kategorie {
display: none;
}
}
Diese Technik ist nur vertretbar, wenn die ausgeblendeten Angaben tatsächlich
entbehrlich sind oder an anderer Stelle vollständig zugänglich bleiben. Bei wichtigen
Tabellendaten ist ein horizontaler Scrollbereich meistens die bessere Lösung.
Wichtig:
Das Ausblenden einer Überschriftenspalte erfordert auch das Ausblenden aller zugehörigen
Datenzellen. Andernfalls stimmen Überschriften und Daten nicht mehr überein.
Tabellen nicht unnötig mit CSS umbauen
Eine Tabelle kann auf kleinen Bildschirmen optisch in Karten oder untereinanderstehende
Blöcke umgewandelt werden. Dabei wird häufig die normale Tabellenanzeige durch
display: block ersetzt.
@media (max-width: 767.98px) {
table,
thead,
tbody,
tr,
th,
td {
display: block;
}
}
Eine solche Umgestaltung kann die Beziehungen zwischen Überschriften und Daten
unübersichtlich machen. Außerdem sind zusätzliche Beschriftungen und sorgfältige Tests
mit Tastatur und Screenreader erforderlich.
Empfehlung:
Für Lernbeispiele und gewöhnliche Datentabellen sollte zuerst eine echte HTML-Tabelle in
einem horizontal scrollbaren Container verwendet werden. Dadurch bleibt die semantische
Tabellenstruktur erhalten.
Vollständiges responsives Beispiel
<p class="scroll-hinweis">
Auf kleinen Bildschirmen kann die Tabelle seitlich verschoben werden.
</p>
<div
class="table-scroll"
tabindex="0"
role="region"
aria-label="Lagerbestand für Computerzubehör"
>
<table class="preisliste">
<caption>Lagerbestand für Computerzubehör</caption>
<thead>
<tr>
<th scope="col">Artikelnummer</th>
<th scope="col">Produkt</th>
<th scope="col">Kategorie</th>
<th scope="col">Bestand</th>
<th scope="col">Preis</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">EDV-1001</th>
<td>Mechanische Tastatur</td>
<td>Eingabegeräte</td>
<td>24 Stück</td>
<td>89,90 €</td>
</tr>
<tr>
<th scope="row">EDV-1002</th>
<td>Kabellose Maus</td>
<td>Eingabegeräte</td>
<td>38 Stück</td>
<td>39,90 €</td>
</tr>
</tbody>
</table>
</div>
.table-scroll {
max-width: 100%;
overflow-x: auto;
}
.table-scroll:focus {
outline: 3px solid #0d6efd;
outline-offset: 2px;
}
.preisliste {
width: 100%;
min-width: 700px;
border-collapse: collapse;
}
.preisliste caption {
padding: 0.75rem;
font-size: 1.25rem;
font-weight: bold;
text-align: left;
}
.preisliste th,
.preisliste td {
padding: 0.75rem;
border: 1px solid #adb5bd;
text-align: left;
}
.preisliste thead {
background-color: #343a40;
color: #fff;
}
.preisliste tbody tr:nth-child(even) {
background-color: #f2f2f2;
}
.preisliste th:last-child,
.preisliste td:last-child {
text-align: right;
white-space: nowrap;
}
.scroll-hinweis {
display: none;
}
@media (max-width: 767.98px) {
.scroll-hinweis {
display: block;
font-size: 0.9rem;
}
}
Die Tabelle bleibt semantisch vollständig erhalten. Auf großen Bildschirmen nutzt sie
die verfügbare Breite. Auf kleinen Bildschirmen kann sie innerhalb ihres Containers
horizontal verschoben werden.