Header Bild

Responsive Tabelle mit Bootstrap Raster

Wie vermutlich viele von euch, stand auch ich irgendwann vor dem Problem, dass ich eine HTML-Tabelle hatte, die ich auf Mobilgeräten sauber anzeigen wollte. Ohne horizontalen Scroll Aufwand. Dies gestaltet sich schwierig, da die meisten Tabellen auf Breite ausgelegt sind. Wenn man eine Tabelle mit fünf oder sechs Spalten hat, die auch noch Inhalt anzeigen sollen, kann das schnell kompliziert werden.

Bootstrap Raster statt HTML Table

Dann kam mir die Idee, das Ganze nicht mit einer Tabelle abzubilden, sondern mit einem Bootstrap Raster. Das Raster, welches sich aus zwölf Rasterteilen (Spalten) zusammensetzt, ist wie geschaffen, um eine Tabelle nachzubilden. Der Vorteil hierbei ist, dass das Raster automatisch, je nach Auflösung des Gerätes, auf dem es angezeigt wird, umbricht. Das Ziel ist es also, wenn der Bildschirm zu schmal wird, in einer Zeile die Zellen zu stapeln. So wird eine Zeile dann in zwei oder drei Zeilen dargestellt.

Als Beispiel nehmen wir eine Tabelle, die Namen und Adressdaten darstellt. Wir haben also sechs Spalten:

  • Vorname
  • Nachname
  • Straße
  • Hausnummer
  • PLZ
  • Stadt

Bei einem 12er Raster ergeben sich somit gleichmäßig sechs Spalten mit einer 2er Rasterbreite. Allerdings würde ich für die Hausnummer nur eine 1-fache Rasterbreite nehmen und dafür die Straße auf eine 3er erweitern.

Die Tabelle

Unsere Tabelle würden wir dann so erstellen:

<div class="container-fluid">
	<div class="row">
		<div class="col-2 p-1 border text-center fw-bold">Vorname</div>
		<div class="col-2 p-1 border text-center fw-bold">Nachname</div>
		<div class="col-3 p-1 border text-center fw-bold">Straße</div>
		<div class="col-1 p-1 border text-center fw-bold">Haus-<br>nummer</div>
		<div class="col-2 p-1 border text-center fw-bold">PLZ</div>
		<div class="col-2 p-1 border text-center fw-bold">Ort</div>
	</div>
	<div class="row">
		<div class="col-2 p-1 border text-center">Dirk</div>
		<div class="col-2 p-1 border text-center">Baier</div>
		<div class="col-3 p-1 border text-center">Kurfürstendamm</div>
		<div class="col-1 p-1 border text-center">36</div>
		<div class="col-2 p-1 border text-center">18069</div>
		<div class="col-2 p-1 border text-center">Allershagen</div>
	</div>
	<div class="row">
		<div class="col-2 p-1 border text-center">Petra</div>
		<div class="col-2 p-1 border text-center">Hueber</div>
		<div class="col-3 p-1 border text-center">Eichendorffstr.</div>
		<div class="col-1 p-1 border text-center">82</div>
		<div class="col-2 p-1 border text-center">88379</div>
		<div class="col-2 p-1 border text-center">Guggenhausen</div>
	</div>
	<div class="row">
		<div class="col-2 p-1 border text-center">Silke</div>
		<div class="col-2 p-1 border text-center">Baecker</div>
		<div class="col-3 p-1 border text-center">Knesebeckstraße</div>
		<div class="col-1 p-1 border text-center">1</div>
		<div class="col-2 p-1 border text-center">52156</div>
		<div class="col-2 p-1 border text-center">Monschau</div>
	</div>
	<div class="row">
		<div class="col-2 p-1 border text-center">Jan</div>
		<div class="col-2 p-1 border text-center">Richter</div>
		<div class="col-3 p-1 border text-center">Hollander Strasse</div>
		<div class="col-1 p-1 border text-center">13</div>
		<div class="col-2 p-1 border text-center">56370</div>
		<div class="col-2 p-1 border text-center">Bremberg</div>
	</div>
	<div class="row">
		<div class="col-2 p-1 border text-center">Annett</div>
		<div class="col-2 p-1 border text-center">Fisher</div>
		<div class="col-3 p-1 border text-center">Heinrich Heine Platz</div>
		<div class="col-1 p-1 border text-center">10</div>
		<div class="col-2 p-1 border text-center">99853</div>
		<div class="col-2 p-1 border text-center">Gotha</div>
	</div>
</div>

Und das wäre das Ergebnis:

Vorname
Nachname
Straße
Haus-
nummer
PLZ
Ort
Dirk
Baier
Kurfürstendamm
36
18069
Allershagen
Petra
Hueber
Eichendorffstr.
82
88379
Guggenhausen
Silke
Baecker
Knesebeckstraße
1
52156
Monschau
Jan
Richter
Hollander Strasse
13
56370
Bremberg
Annett
Fisher
Heinrich Heine Platz
10
99853
Gotha

Um euch das entsprechend anzuschauen, könnt ihr im Browser in den Entwickleroptionen, meist mit der Taste F12 aufrufbar, die Mobilgeräte-Emulation aktivieren. Diese kann auch häufig über strg + shift + M direkt aufgerufen werden.

Wie ihr seht, wird die Spalte Hausnummer auf Geräten mit einer Breite von 768px schon recht knapp. Hierfür bietet Bootstrap die passende Lösung. Über verschiedene Klassen ist einstellbar auf welcher Display Größe wie viel Anteile des 12er Rasters eingenommen werden sollen. Hierbei ist der Mobile First Ansatz zu beachten. Ich fange also mit der kleinsten Darstellungsart an und lege fest, wie viele Rasterteile die einzelnen Spalten einnehmen sollen. Eine col-6 Klasse gibt als Beispiel an, dass eine Spalte sich über sechs Rasterteile, also den halben Bildschirm, erstreckt. Bei Bildschirmen <576px. Wird das Element auf größeren Displays dargestellt, bleibt es bei sechs Rasterteilen. Wird jedoch in demselben Element noch eine col-md-3 Klasse definiert, so wechselt das Element bei Überschreiten einer Bildschirmgröße von 768px auf drei Rasterteile. Wir können die Zellen also bei kleinen Bildschirmen größer machen und sie dafür stapeln. Ich würde dann in diesem speziellen Fall auf ein drei-zeiliges Layout bei kleinen Bildschirmen gehen.

Hier der Code:

<div class="container-fluid">
	<div class="row my-2">
		<div class="col-6 p-1 border text-center fw-bold">Vorname</div>
		<div class="col-6 p-1 border text-center fw-bold">Nachname</div>
		<div class="col-9 p-1 border text-center fw-bold">Straße</div>
		<div class="col-3 p-1 border text-center fw-bold">Haus-<br>nummer</div>
		<div class="col-6 p-1 border text-center fw-bold">PLZ</div>
		<div class="col-6 p-1 border text-center fw-bold">Ort</div>
	</div>
	<div class="row my-2">
		<div class="col-6 p-1 border text-center">Dirk</div>
		<div class="col-6 p-1 border text-center">Baier</div>
		<div class="col-9 p-1 border text-center">Kurfürstendamm</div>
		<div class="col-3 p-1 border text-center">36</div>
		<div class="col-6 p-1 border text-center">18069</div>
		<div class="col-6 p-1 border text-center">Allershagen</div>
	</div>
	<div class="row my-2">
		<div class="col-6 p-1 border text-center">Petra</div>
		<div class="col-6 p-1 border text-center">Hueber</div>
		<div class="col-9 p-1 border text-center">Eichendorffstr.</div>
		<div class="col-3 p-1 border text-center">82</div>
		<div class="col-6 p-1 border text-center">88379</div>
		<div class="col-6 p-1 border text-center">Guggenhausen</div>
	</div>
	<div class="row my-2">
		<div class="col-6 p-1 border text-center">Silke</div>
		<div class="col-6 p-1 border text-center">Baecker</div>
		<div class="col-9 p-1 border text-center">Knesebeckstraße</div>
		<div class="col-3 p-1 border text-center">1</div>
		<div class="col-6 p-1 border text-center">52156</div>
		<div class="col-6 p-1 border text-center">Monschau</div>
	</div>
	<div class="row my-2">
		<div class="col-6 p-1 border text-center">Jan</div>
		<div class="col-6 p-1 border text-center">Richter</div>
		<div class="col-9 p-1 border text-center">Hollander Strasse</div>
		<div class="col-3 p-1 border text-center">13</div>
		<div class="col-6 p-1 border text-center">56370</div>
		<div class="col-6 p-1 border text-center">Bremberg</div>
	</div>
	<div class="row my-2">
		<div class="col-6 p-1 border text-center">Annett</div>
		<div class="col-6 p-1 border text-center">Fisher</div>
		<div class="col-9 p-1 border text-center">Heinrich Heine Platz</div>
		<div class="col-3 p-1 border text-center">10</div>
		<div class="col-6 p-1 border text-center">99853</div>
		<div class="col-6 p-1 border text-center">Gotha</div>
	</div>
</div>

Und so siehts aus:

Vorname
Nachname
Straße
Haus-
nummer
PLZ
Ort
Dirk
Baier
Kurfürstendamm
36
18069
Allershagen
Petra
Hueber
Eichendorffstr.
82
88379
Guggenhausen
Silke
Baecker
Knesebeckstraße
1
52156
Monschau
Jan
Richter
Hollander Strasse
13
56370
Bremberg
Annett
Fisher
Heinrich Heine Platz
10
99853
Gotha

Ich habe, um die Übersicht etwas zu verbessern, die Tabellenzeilen mit einem Abstand my-2 versehen. my bedeutet Margin auf der Y-Achse, also vertikal.

Wenn ihr euch das Ergebnis nun mal auf einer Smartphone Auflösung anschaut, seht ihr, dass die Aufteilung gut passt. Dadurch, dass wir jede Tabellenzeile auf drei Zeilen stapeln, haben wir keinen Überlauf an Inhalt und müssen nicht horizontal scrollen.

Um die Tabelle bei größeren Bildschirmen wieder korrekt darzustellen, füge ich nun die entsprechenden Klassen ein. Ich nehme die col-lg-* Klassen. Damit bricht das Raster bei Auflösungen ≥992px um. Somit habe ich bei Tablets immer noch die gestapelte Ansicht und darüber dann die normale Tabellen-Ansicht.

Hier der Code:

<div class="container-fluid">
	<div class="row my-2 my-lg-0">
		<div class="col-6 col-lg-2 p-1 border text-center fw-bold">Vorname</div>
		<div class="col-6 col-lg-2 p-1 border text-center fw-bold">Nachname</div>
		<div class="col-9 col-lg-3 p-1 border text-center fw-bold">Straße</div>
		<div class="col-3 col-lg-1 p-1 border text-center fw-bold">Haus-<br>nummer</div>
		<div class="col-6 col-lg-2 p-1 border text-center fw-bold">PLZ</div>
		<div class="col-6 col-lg-2 p-1 border text-center fw-bold">Ort</div>
	</div>
	<div class="row my-2 my-lg-0">
		<div class="col-6 col-lg-2 p-1 border text-center">Dirk</div>
		<div class="col-6 col-lg-2 p-1 border text-center">Baier</div>
		<div class="col-9 col-lg-3 p-1 border text-center ">Kurfürstendamm</div>
		<div class="col-3 col-lg-1 p-1 border text-center">36</div>
		<div class="col-6 col-lg-2 p-1 border text-center">18069</div>
		<div class="col-6 col-lg-2 p-1 border text-center">Allershagen</div>
	</div>
	<div class="row my-2 my-lg-0">
		<div class="col-6 col-lg-2 p-1 border text-center">Petra</div>
		<div class="col-6 col-lg-2 p-1 border text-center">Hueber</div>
		<div class="col-9 col-lg-3 p-1 border text-center">Eichendorffstr.</div>
		<div class="col-3 col-lg-1 p-1 border text-center">82</div>
		<div class="col-6 col-lg-2 p-1 border text-center">88379</div>
		<div class="col-6 col-lg-2 p-1 border text-center">Guggenhausen</div>
	</div>
	<div class="row my-2 my-lg-0">
		<div class="col-6 col-lg-2 p-1 border text-center">Silke</div>
		<div class="col-6 col-lg-2 p-1 border text-center">Baecker</div>
		<div class="col-9 col-lg-3 p-1 border text-center">Knesebeckstraße</div>
		<div class="col-3 col-lg-1 p-1 border text-center">1</div>
		<div class="col-6 col-lg-2 p-1 border text-center">52156</div>
		<div class="col-6 col-lg-2 p-1 border text-center">Monschau</div>
	</div>
	<div class="row my-2 my-lg-0">
		<div class="col-6 col-lg-2 p-1 border text-center">Jan</div>
		<div class="col-6 col-lg-2 p-1 border text-center">Richter</div>
		<div class="col-9 col-lg-3 p-1 border text-center">Hollander Strasse</div>
		<div class="col-3 col-lg-1 p-1 border text-center">13</div>
		<div class="col-6 col-lg-2 p-1 border text-center">56370</div>
		<div class="col-6 col-lg-2 p-1 border text-center">Bremberg</div>
	</div>
	<div class="row my-2 my-lg-0">
		<div class="col-6 col-lg-2 p-1 border text-center">Annett</div>
		<div class="col-6 col-lg-2 p-1 border text-center">Fisher</div>
		<div class="col-9 col-lg-3 p-1 border text-center">Heinrich Heine Platz</div>
		<div class="col-3 col-lg-1 p-1 border text-center">10</div>
		<div class="col-6 col-lg-2 p-1 border text-center">99853</div>
		<div class="col-6 col-lg-2 p-1 border text-center">Gotha</div>
	</div>
</div>

Und so siehts aus:

Vorname
Nachname
Straße
Haus-
nummer
PLZ
Ort
Dirk
Baier
Kurfürstendamm
36
18069
Allershagen
Petra
Hueber
Eichendorffstr.
82
88379
Guggenhausen
Silke
Baecker
Knesebeckstraße
1
52156
Monschau
Jan
Richter
Hollander Strasse
13
56370
Bremberg
Annett
Fisher
Heinrich Heine Platz
10
99853
Gotha

Mit hinzufügen der Klasse my-lg-0 in das div.row entferne ich den Abstand zwischen den Zeilen bei der größeren Auflösung wieder. Wie oben schon erklärt ergibt sich aus der Kombination col-6 col-lg-2, dass bei kleinem Bildschirm 6 Rasterteile für die Spalte genommen werden und beim Darstellen auf Bildschirmen ≥992px dann nur noch 2 Rasterteile. Somit wird aus der gestapelten 3er Zeile eine normale Zeile.

Die Rahmen

Wen die Rahmen stören, der muss leider mit CSS nachhelfen. Nehmt dann die border Klasse überall raus und macht den Rahmen über eine CSS Media Query für die genutzten Bildschirmgrößen. In unserem Beispiel wären das max-width:991px und min-width:992px.

Für die letzte Tabelle wäre der Code dann der Folgende.

CSS:

@media (max-width:991px) {
	.row-border {
		border-top:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color);
		border-left:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color);
	}
	.col-border {
		border-bottom:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color);
		border-right:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color);
	}
}
@media (min-width:992px) {
	.container-border {
		border-top:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color);
		border-left:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color);
	}
	.row-border {
		border-bottom:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color);
	}
	.col-border {
		border-right:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color);
	}
}

HTML:

<div class="container-fluid container-border">
	<div class="row row-border my-2 my-lg-0">
		<div class="col-border col-6 col-lg-2 p-1 text-center fw-bold">Vorname</div>
		<div class="col-border col-6 col-lg-2 p-1 text-center fw-bold">Nachname</div>
		<div class="col-border col-9 col-lg-3 p-1 text-center fw-bold">Straße</div>
		<div class="col-border col-3 col-lg-1 p-1 text-center fw-bold">Haus-<br>nummer</div>
		<div class="col-border col-6 col-lg-2 p-1 text-center fw-bold">PLZ</div>
		<div class="col-border col-6 col-lg-2 p-1 text-center fw-bold">Ort</div>
	</div>
	<div class="row row-border my-2 my-lg-0">
		<div class="col-border col-6 col-lg-2 p-1 text-center">Dirk</div>
		<div class="col-border col-6 col-lg-2 p-1 text-center">Baier</div>
		<div class="col-border col-9 col-lg-3 p-1 text-center ">Kurfürstendamm</div>
		<div class="col-border col-3 col-lg-1 p-1 text-center">36</div>
		<div class="col-border col-6 col-lg-2 p-1 text-center">18069</div>
		<div class="col-border col-6 col-lg-2 p-1 text-center">Allershagen</div>
	</div>
	<div class="row row-border my-2 my-lg-0">
		<div class="col-border col-6 col-lg-2 p-1 text-center">Petra</div>
		<div class="col-border col-6 col-lg-2 p-1 text-center">Hueber</div>
		<div class="col-border col-9 col-lg-3 p-1 text-center">Eichendorffstr.</div>
		<div class="col-border col-3 col-lg-1 p-1 text-center">82</div>
		<div class="col-border col-6 col-lg-2 p-1 text-center">88379</div>
		<div class="col-border col-6 col-lg-2 p-1 text-center">Guggenhausen</div>
	</div>
	<div class="row row-border my-2 my-lg-0">
		<div class="col-border col-6 col-lg-2 p-1 text-center">Silke</div>
		<div class="col-border col-6 col-lg-2 p-1 text-center">Baecker</div>
		<div class="col-border col-9 col-lg-3 p-1 text-center">Knesebeckstraße</div>
		<div class="col-border col-3 col-lg-1 p-1 text-center">1</div>
		<div class="col-border col-6 col-lg-2 p-1 text-center">52156</div>
		<div class="col-border col-6 col-lg-2 p-1 text-center">Monschau</div>
	</div>
	<div class="row row-border my-2 my-lg-0">
		<div class="col-border col-6 col-lg-2 p-1 text-center">Jan</div>
		<div class="col-border col-6 col-lg-2 p-1 text-center">Richter</div>
		<div class="col-border col-9 col-lg-3 p-1 text-center">Hollander Strasse</div>
		<div class="col-border col-3 col-lg-1 p-1 text-center">13</div>
		<div class="col-border col-6 col-lg-2 p-1 text-center">56370</div>
		<div class="col-border col-6 col-lg-2 p-1 text-center">Bremberg</div>
	</div>
	<div class="row row-border my-2 my-lg-0">
		<div class="col-border col-6 col-lg-2 p-1 text-center">Annett</div>
		<div class="col-border col-6 col-lg-2 p-1 text-center">Fisher</div>
		<div class="col-border col-9 col-lg-3 p-1 text-center">Heinrich Heine Platz</div>
		<div class="col-border col-3 col-lg-1 p-1 text-center">10</div>
		<div class="col-border col-6 col-lg-2 p-1 text-center">99853</div>
		<div class="col-border col-6 col-lg-2 p-1 text-center">Gotha</div>
	</div>
</div>

Und so siehts aus:

Vorname
Nachname
Straße
Haus-
nummer
PLZ
Ort
Dirk
Baier
Kurfürstendamm
36
18069
Allershagen
Petra
Hueber
Eichendorffstr.
82
88379
Guggenhausen
Silke
Baecker
Knesebeckstraße
1
52156
Monschau
Jan
Richter
Hollander Strasse
13
56370
Bremberg
Annett
Fisher
Heinrich Heine Platz
10
99853
Gotha

Ich habe den einzelnen <div></div> jeweils noch eine *-border Klasse gegeben, um sie separat von anderen Elementen anzusprechen. Oben im <style></style> Block findet sich der simple CSS code. Für Rahmen-Dicke, -Farbe und -Format habe ich die Bootstrap Variablen genutzt, die auch bei Nutzung der Bootstrap border Klasse genutzt werden würden. Wer die Eigenschaften selbst vergeben möchte, kann diese natürlich frei anpassen.

Noch mehr Displaygrößen

Das Ganze ist, bei noch mehr Spalten, natürlich noch erweiterbar für die Darstellung auf noch mehr Displaygrößen. Wenn ich eine Tabelle mit acht oder neun Spalten habe, kann ich diese auf der kleinsten Displaygröße <576px auf fünf Zeilen stapeln. Auf Displays ≥576px staple ich dann nur noch auf vier Zeilen. Bei ≥768px gehe ich auf drei Zeilen usw. So kann ich die Tabelle für jede Displaygröße neugestalten. Ich kann über die order-* Klassen sogar die Reihenfolge der Zellen anpassen. So könnte ich in unserem Beispiel dafür sorgen, dass Vorname und Name auf dem Smartphone als letztes angezeigt werden. Hierfür müsste ich den div.col-* für Vor- und Nachname nur die Klassen order-2 order-lg-1 geben und den anderen div.col-* die Klassen order-1 order-lg-2. Das hat zur Folge, dass sie bei kleinen Displays in der Reihenfolge getauscht und bei Displays ≥992px wieder richtig gesetzt werden.

Ich hoffe ich konnte euch hiermit etwas helfen, schöne und responsive Tabellen zu erstellen. Feedback gerne als Kommentar.

Kommentare

Schreibe einen Kommentar