Zum Hauptinhalt springen

Responsive HTML-Tabellen

Responsive HTML-Tabellen

HTML-Tabellen sind praktisch, wenn strukturierte Daten übersichtlich dargestellt werden sollen: Preislisten, Kursübersichten, technische Vergleiche, Terminpläne oder Auswertungen. Auf großen Bildschirmen funktioniert das meistens problemlos. Auf Smartphones und Tablets sieht es anders aus: Viele Spalten, lange Inhalte und feste Tabellenbreiten führen schnell dazu, dass Inhalte abgeschnitten werden oder nur mit umständlichem Zoomen lesbar sind.

Für die Suchmaschinenoptimierung ist das ebenfalls relevant. Google bewertet Websites nach dem Mobile-First-Prinzip: Für Indexierung und Ranking wird vor allem die mobile Version einer Seite herangezogen. Inhalte sollten deshalb auch auf kleinen Bildschirmen vollständig zugänglich und gut nutzbar sein.

In diesem Beitrag zeigen wir drei Möglichkeiten, wie HTML-Tabellen responsiv umgesetzt werden können:

  1. horizontales Scrollen per CSS
  2. eine JavaScript-Variante mit sichtbarer Tabellenkopfzeile
  3. eine HTML5-/CSS3-Lösung, bei der die Tabelle auf kleinen Bildschirmen umformatiert wird

Welche Variante sinnvoll ist, hängt vom Inhalt der Tabelle, der Zielgruppe und dem gewünschten Bedienkomfort ab.

Warum sind responsive HTML-Tabellen schwierig?

Responsive Webdesign lässt sich bei Texten, Bildern und flexiblen Layouts meist gut umsetzen. Tabellen sind anspruchsvoller, weil sie eine feste Struktur aus Zeilen und Spalten haben. Gerade bei vielen Spalten entsteht auf kleinen Bildschirmen schnell ein Platzproblem.

Typische Probleme sind:

  • Die Tabelle ist breiter als der Bildschirm.
  • Spalten werden zu schmal und Inhalte brechen unschön um.
  • Nutzer müssen horizontal scrollen.
  • Die Kopfzeile verschwindet beim Scrollen.
  • Die Bedeutung einzelner Werte ist auf dem Smartphone nicht mehr klar erkennbar.

Deshalb reicht es oft nicht, eine Tabelle einfach nur „kleiner“ darzustellen. Häufig muss entschieden werden, ob die Tabelle scrollbar bleibt oder ob die Inhalte für mobile Geräte anders strukturiert werden.

Variante 1: Tabelle horizontal scrollbar machen

Die einfachste Lösung besteht darin, die Tabelle in einen Container zu setzen und diesem Container horizontales Scrollen zu erlauben.

<div class="table-container">
    <table>
        ...
    </table>
</div>
.table-container {
    overflow-x: auto;
}

Damit bleibt die Tabelle in ihrer ursprünglichen Struktur erhalten. Ist sie breiter als der verfügbare Platz, kann der Nutzer seitlich scrollen.

Vorteile dieser Variante

Diese Lösung ist schnell umgesetzt und benötigt kein JavaScript. Die Tabellenstruktur bleibt vollständig erhalten. Gerade bei einfachen Tabellen oder bei technischen Daten, bei denen die Spaltenlogik wichtig ist, kann das eine akzeptable Lösung sein.

Nachteile dieser Variante

Aus Sicht der Benutzerfreundlichkeit ist horizontales Scrollen nicht immer ideal. Bei längeren Tabellen verschwindet die Kopfzeile schnell aus dem sichtbaren Bereich. Nutzer müssen sich dann merken, welche Spalte welche Bedeutung hat. Besonders auf Smartphones kann das mühsam werden.

Diese Variante eignet sich daher vor allem für kleinere Tabellen oder für Tabellen, bei denen die Nutzer mit horizontalem Scrollen rechnen.

Variante 1 ist geeignet für einfache Tabellen, technische Übersichten, kurze Preis- oder Vergleichstabellen.

Variante 1 ist weniger geeignet für lange Tabellen mit vielen Zeilen und erklärungsbedürftigen Spalten.

Variante 2: Responsive Tabelle mit JavaScript und sichtbarer Kopfzeile

Die zweite Möglichkeit verbessert die erste Variante. Die Tabelle bleibt grundsätzlich breit und kann weiterhin horizontal gescrollt werden. Zusätzlich wird die Kopfzeile per JavaScript sichtbar gehalten, solange sich die Tabelle im sichtbaren Bereich befindet. Ist JavaScript deaktiviert oder wird nicht unterstützt, verhält sich diese Variante ähnlich zu Variante 1.

Das Ziel: Nutzer sollen beim Scrollen weiterhin erkennen können, welche Bedeutung die einzelnen Spalten haben.

Grundidee der JavaScript-Lösung

Bei dieser Variante wird nicht die originale Kopfzeile der Tabelle fixiert. Stattdessen erzeugt JavaScript eine zweite Tabelle, die nur aus der Kopfzeile besteht. Diese zusätzliche Kopfzeile wird oben eingeblendet, wenn die eigentliche Tabelle sichtbar ist.

Dafür benötigen wir zwei Event-Listener:

  • scroll: prüft, ob die Tabelle im sichtbaren Bereich liegt und passt die Position der Kopfzeile an
  • resize: berechnet die Spaltenbreiten neu, wenn sich die Fenstergröße ändert
var timer = null;
var table = document.getElementById("table-1");
var headerTable = null;
var tableColumns = new Array();
var headerTableColumns = new Array();
if(table){
    var heading = table.getElementsByTagName("thead")[0].getElementsByTagName("tr")[0];
    if(heading){
        document.getElementsByTagName("body")[0].className += "js-enabled";
        var columns = heading.getElementsByTagName("th");
        var countOfColumns = columns.length; 
        var headerRow = document.createElement("tr");
        var headerTableContainer = document.createElement("div");
        headerTable = document.createElement("table");
        for (var i = 0; i < countOfColumns; i++){
            var column = document.createElement("th");
            column.appendChild(document.createTextNode(columns[i].firstChild.nodeValue));
            headerRow.appendChild(column);
            tableColumns.push(columns[i]);
            headerTableColumns.push(column);
        }
        headerTable.className = "header-table";
        headerTable.appendChild(headerRow);     
        headerTableContainer.className = "header-table-container";
        headerTableContainer.appendChild(headerTable);
        document.getElementsByTagName("body")[0].appendChild(headerTableContainer);

        updateHeaderTableWidth();
        if(window != null && typeof(window) != "undefined"){
            if(window.addEventListener) {
                window.addEventListener("resize", resetTableWidth, false);
                window.addEventListener("scroll", scrolling, false);
            } else {
                if (window.attachEvent) {
                    window.attachEvent("onresize", resetTableWidth);
                    window.attachEvent("onscroll", scrolling);
                } else {
                    window["onresize"] = resetTableWidth;
                    window["onscroll"] = scrolling;
                }
            }
        }
    }
}

Die 5 erwähnten Variablen haben folgende Bedeutung:

  1. timer: Den Timer nutzen wir, damit unsere Methode für das Resize-Event nicht sofort ausgeführt wird. Würden wir den Timer nicht nutzen, würde eine Neuberechnung der Spaltenbreiten sofort geschehen. Dies kann zu Performance-Einbußen führen.
  2. table: Die Variable speichert den Zugriff, auf die Tabelle, die den Inhalte enthält.
  3. headerTable: Das ist unsere zweite Tabelle, die die Kopfzeile enthält.
  4. tableColumns: Die Variable enthalt die Zellen der Originaltabelle (genauer gesagt der Kopfzeile der Originaltabelle)
  5. headerTableColumns: Die Variable enthalt die Zellen der neuen Tablle mit den Kopfzeilen.

Direkt nach der Deklaration der Variablen folgt das erste Skript. Es erstellt beim Seitenaufruf unsere zweite Tabelle mit den Kopfspalten, merkt sich die Kopfspaltenzellen der Originaltabelle und erstellt unsere Event-Listener.

Anschließend definieren wir noch 3 Funktionen.

function resetTableWidth(){
    if (timer != null){
        window.clearTimeout(timer);
        timer = null;
    }
    timer = window.setTimeout("updateHeaderTableWidth()", 1000);
}

Diese Funktion wird bei jeder Änderung der Browserfenstergröße aufgerufen. Wir könnten sofort die Berechnung der Spaltenbreiten unserer zweiten Tabelle anstoßen. Da die Funktion bei der kleinsten Änderung aufgerufen wird, würde das Skript millisekündlich laufen, währen der Benutzer das Browserfenster skaliert. Millisekündlich müssten wir die neue Breite berechnen. Das kann dazu führen, das der Browser gar nicht oder schlecht reagiert. Um dies zu verhindern, nutzen wir einen Timer. In diesem Fall von einer Sekunde. Eine Sekunde nachdem der Benutzer aufhört, die Größe des Browserfenster zu ändern, wird die Funktion updateHeaderTableWidth aufgerufen.

function updateHeaderTableWidth(){
    if(headerTableColumns.length <= 0 || tableColumns.length <= 0 || headerTableColumns.length != tableColumns.length){
        return;
    }
    var countOfColumns = headerTableColumns.length;
    for (var i = 0; i < countOfColumns; i++){
        headerTableColumns[i].style.width = tableColumns[i].offsetWidth + "px";
    }
    headerTable.style.width = table.offsetWidth + "px";
}

In dieser Funktion weisen wir den Tabellenzellen der zweiten Tabelle die Breite der Originaltabellenkopfzeilen zu. Wir haben uns im ersten Skriptbereich die Zellen in zwei Variablen gespeichert. Am Ende weisen wir noch die Breite der zweiten Tabelle die Breiet der Originaltabelle zu. Das verhindert, dass es eine Lücke in der zweiten Tabelle gibt. Im Normalfall sind die Spaltenbreiten keine ganzen Pixel. Die Summe der einzelnen Spalten kann dadurch kleiner sein als die Breiet der gesamten Tabelle.

Beim Scrollen soll die zusätzliche Kopfzeile ein- oder ausgeblendet werden. Dazu dient unsere dritte Methode:

function scrolling(){
    headerTable.style.marginLeft = -window.pageXOffset + "px";
    if(window.pageYOffset <= 0 && table.offsetTop == 0 ||(window.pageYOffset >= table.offsetTop && window.pageYOffset < table.offsetTop + table.offsetHeight - headerTable.offsetHeight - 10)){
        headerTable.style.display = "block";
    }
    else{
        headerTable.style.display = "none";
    }
}

Vorteile dieser Variante

Die Tabelle bleibt in ihrer ursprünglichen Struktur erhalten. Gleichzeitig bleibt die Kopfzeile sichtbar, was die Orientierung deutlich verbessert. Das ist besonders hilfreich bei Tabellen mit vielen Spalten oder vielen Zeilen.

Nachteile dieser Variante

Die Lösung ist aufwendiger als reines CSS. Außerdem funktioniert sie nur, wenn JavaScript beim Nutzer aktiviert ist. Das ist heute zwar in den meisten Fällen gegeben, sollte aber trotzdem bedacht werden – vor allem in Bezug auf Barrierefreiheit.

Außerdem löst diese Variante nicht das Grundproblem sehr breiter Tabellen: Auf kleinen Bildschirmen muss weiterhin horizontal gescrollt werden.

Variante 2 ist geeignet für umfangreiche Tabellen, technische Daten, Tabellen mit vielen Zeilen.

Variante 2 ist weniger geeignet für sehr einfache Tabellen oder Inhalte, die auf Smartphones besser als Karten dargestellt werden sollten.

Variante 3: HTML5- und CSS3-Lösung mit data-Attributen

Die dritte Variante geht einen anderen Weg. Die Tabelle wird auf kleinen Bildschirmen nicht horizontal gescrollt, sondern in eine vertikale Darstellung umgewandelt. Jede Tabellenzeile wird dabei wie ein eigener Block dargestellt.

So kann aus einer klassischen Tabelle auf dem Desktop eine gut lesbare mobile Ansicht entstehen.

HTML der Tabelle erweitern

Damit die Spaltenbezeichnungen auch in der mobilen Ansicht sichtbar bleiben, werden data-Attribute verwendet. Diese Attribute sind im Browser zunächst nicht direkt sichtbar, können aber per CSS ausgegeben werden.

Beispiel:

<tr data-mykey-row="Person 1">
    <td data-mykey-column="Name">Müller</td>
    <td data-mykey-column="Vorname">Hans</td>
</tr>
<tr data-mykey-row="Person 2">
    <td data-mykey-column="Name">Meier</td>
    <td data-mykey-column="Vorname">Gerd</td>
</tr>

Das Attribut data-mykey-row beschreibt die Zeile. Das Attribut data-mykey-column enthält die jeweilige Spaltenbezeichnung. In der mobilen Ansicht kann CSS diese Informationen vor dem eigentlichen Zellinhalt anzeigen.

CSS für die mobile Darstellung

Über eine Media Query legen wir fest, ab welcher Bildschirmbreite die Tabelle umformatiert werden soll. Im folgenden Beispiel geschieht dies bis die Breite des Browserfensters mehr als 60em beträgt.

@media only screen and (max-width: 60em) {
    .table-2 thead{display: none;}
    .table-2 tr, .table-2 td, .table-2 tr:before{display: block;}
    .table-2 tr{padding-top: 0.5em; background:  #076c84;}
    .table-2 td:before{content: attr(data-mykey-column)": ";}
    .table-2 tr:before{content: attr(data-mykey-row)": "; padding-left: 0.5em; padding-bottom: 0.5em; color:#fff;}
}

Die Kopfzeile wird in der mobilen Ansicht ausgeblendet. Zeilen und Zellen werden Block-Elemente. Mit den letzten zwei Anweisungen werden das Objekt und die Spaltenbeschriftungen ausgegeben.

Aus einer klassischen Tabellenzeile wie:

NameVorname
MüllerHans
MeierGerd

wird auf dem Smartphone sinngemäß:

Person 1
Name: Müller
Vorname: Hans

Person 2
Name: Meier
Vorname: Gerd

Vorteile dieser Variante

Diese Lösung ist für Smartphones besonders gut lesbar. Nutzer müssen nicht horizontal scrollen. Jede Zeile wird als eigener Inhaltsblock dargestellt. Gerade bei Tabellen mit wenigen bis mittleren Spalten kann das die beste mobile Nutzererfahrung bieten.

Nachteile dieser Variante

Die HTML-Struktur muss erweitert werden. Außerdem eignet sich diese Variante nicht für jede Tabelle. Wenn Nutzer Werte über viele Spalten hinweg direkt vergleichen müssen, kann die umformatierte Darstellung unübersichtlicher sein als eine klassische Tabelle.

Variante 3 ist geeignet für Kontaktlisten, Kursübersichten, einfache Produktdaten, Preis- oder Terminlisten.

Variante 3 ist weniger geeignet für komplexe Vergleichstabellen, sehr große Datensätze, Tabellen mit vielen numerischen Spalten.

Welche Variante ist die beste?

Es gibt nicht die eine perfekte Lösung für alle responsive HTML-Tabellen. Die passende Variante hängt von der Art der Daten ab.

AnforderungEmpfohlene Variante
Tabelle soll schnell mobil nutzbar werdenVariante 1
Kopfzeile soll beim Scrollen sichtbar bleibenVariante 2
Tabelle soll auf Smartphones besonders gut lesbar seinVariante 3
Viele technische VergleichswerteVariante 1 oder 2
Wenige Spalten, viele einzelne DatensätzeVariante 3
Kein JavaScript gewünschtVariante 1 oder 3

In vielen Projekten ist Variante 3 die nutzerfreundlichste Lösung für mobile Geräte. Variante 1 ist dagegen die schnellste und einfachste Umsetzung. Variante 2 eignet sich, wenn die Tabellenstruktur unbedingt erhalten bleiben soll, die Orientierung aber verbessert werden muss.

Hinweis: In den Kommentaren wird auch die Möglichkeit erwähnt, mit Bootstrap eine Tabelle anhand von div-Elementen zu erstellen. Wird dies genutzt, so kann für Screenreader nicht mehr erkannt werden, dass es sich um eine Tabelle handelt. Dann muss diese Funktion mit ARIA-Attributen wieder hergestellt werden. Auch Suchmaschinen erkennen eine Tabelle aus div-Elementen im Normalfall nicht mehr als Tabelle. Diese Tabelle sieht nur noch dank CSS aus wie eine Tabelle. Die Struktur einer Tabelle ist nicht mehr gegeben. Dies erkennt man sehr leicht, wenn man im Browser CSS deaktiviert. Eine echte Tabelle (mit dem table-Element) wird vom Browser weiterhin als Tabelle dargestellt. Eine Tabelle aus div-Elementen ist nur noch eine vertikale Aneinanderreihung von Textblöcken.

Kommentar schreiben

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Ein Gedanke zu “Responsive HTML-Tabellen”

  • Holger "der_wasi"
    Geschrieben am 8. November 2025 um 16:06

    Hallo,

    die letzte Variante ist auch schön über Bootstrap zu realisieren. Statt einer Tabelle erstellt man ein Raster und legt so fest, wann die Tabelle anfangen soll, sich zu stapeln. So kann man noch unterschiedliche Darstellungen für Tablet und Smartphone erreichen.
    Genauer habe ich das hier in meinem Blog erklärt:
    https://blog.wasiwarez.net/2024/03/responsive-tabelle-mit-bootstrap-raster/

    Viele Grüße,

    Holger