Zum Hauptinhalt springen

Responsive HTML-Tabellen

Responsive HTML-Tabellen

Das Internet wird immer mobiler. Früher gab es nur Desktop-Geräte. Webdesigns konnten starr gestaltet werden. Websites mussten nicht für kleine Bildschirmgrößen optimiert werden. Dies hat sich seit der Einführung des iPhones im Jahre 2007 grundlegend geändert. Auch Google hat erkannt, dass es immer mehr Mobilgeräte gibt. Keine mobile Website zu haben, kann schädlich sein. Heutzutage sollten Websites auch für kleine Geräte optimiert werden.

Viele Website-Betreiber ignorierten das mobile Internet: „Die Nutzer werden unsere Webseiten nur mit Desktopgeräten ansehen. Wir brauchen keine Anpassung der Webseite für Mobilgeräte.“ Doch spätestens im Jahr 2017 sollte jede Website für Mobilgeräte angepasst sein – oder zu mindestens eine zweite mobilgerechte Version besitzen. Google wird Websites „bestrafen“, die nicht für Mobilgeräte angepasst sind. Websites, die nicht angepasst sind, werden in den SERPs (Suchergebnisseiten) nicht weit oben stehen. Möchte ein Website-Betreiber dies?

Websites für Mobilgeräte anzupassen, ist nicht allzu schwer. Dies gilt natürlich nur, so fern ein Mitarbeiter mit den entsprechenden HTML- und CSS-Kenntnissen im Unternehmen tätig ist. Auf einigen Websites werden allerdings Tabellen eingesetzt (für Inhalte, nicht für Layouts). HTML-Tabellen für Mobilgeräte zu optimieren, ist komplizierter. Einige Möglichkeiten stellen wir Ihnen in diesem Artikel vor.

Variante 1

Die erste Möglichkeit wäre, den Container um der Tabelle (meist ein div-Element) mit der CSS-Eigenschaft

overflow-x: scroll;

auszuzeichnen.

Wenn der Nutzer die Tabelle nach unten scrollt, verschwindet allerdings der Tabellenkopf. Vergisst der Nutzer, welche Bedeutung jede einzelne Spalte hat, muss er aufwendig nach oben und wieder nach unten scrollen. Zudem wird der Nutzer auf einem Gerät mit kleinem Display auch nach rechts und links scrollen müssen. Aus Usability-Sicht ist dies nicht in Ordnung.

Variante 2 mit JavaScript

Es gibt eine Möglichkeit, mit JavaScript eine Tabelle besser für Mobilgeräte zu optimieren. Optimal ist diese Variante nicht, doch es gibt sicherlich auch Einsatzmöglichkeiten für die jetzt erwähnte Variante.

Dieses Beispiel werden wir etwas ausführlicher behandeln als nötig. Wir werden die Breite der Tabelle unangetastet lassen, d.h. die Tabelle wird bei kleineren Bildschirmgrößen nach rechts aus dem Viewport laufen. Die Kopfzeile hingegen soll immer eingeblendet sein (sofern die Tabelle im Anzeigebereich liegt). Tatsächlich wird nicht die Kopfzeile der Inhaltstabelle sichtbar gemacht. Wir werden uns eine zweite Tabelle mit Hilfe von JavaScript erstellen, die nur aus einer Kopfzeile besteht.

Um dies zu bewerkstelligen, benötigen wir zwei Event-Listener. Einmal für das Scroll-Event und einmal für das Resize-Event.

Dank dem Scroll-Event werden wir unsere erstellte Kopfzeile aus- oder einblenden. Ist die Tabelle sichtbar, soll auch die Kopfzeile sichtbar sein. Ist die Tabelle nicht mehr im Viewport zu sehen, so verschwindet auch die Kopfzeile, die sich immer oben am Fensterrand befindet. Zudem werden wir die horizontale Position anpassen, wenn der Nutzer nach rechts oder links scrollt, um die weiteren Spalten der Tabelle anzusehen.

Dank dem Resize-Event werden wir die Spaltenbreite der Kopfzeile anpassen. Ziel ist es, dass die Spaltenbreiten der Inhaltstabelle mit den Spaltenbreiten der Kopfzeile übereinstimmen.

Zusammen mit einigen Variablendeklarationen tun wir dies im Script-Element, welches am Ende des HTML-Dokumentes stehen sollte.

Der erste Teil des Scriptes

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 countOfRows = columns.length; 
		var headerRow = document.createElement("tr");
		var headerTableContainer = document.createElement("div");
		headerTable = document.createElement("table");
		for (var i = 0; i < countOfRows; 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 Variablen

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.

Die Variable table, speichert den Zugriff, auf die Tabelle, die den Inhalte enthält.

Die Variable headerTable ist unsere Tabelle für unsere Kopfzeile.

Die nächsten zwei Variablen speichern jeweils die Spalten der Inhaltstabelle und der Kopfzeilen-Tabelle.

Kopfzeile erstellen und Event-Listener anlegen

Im Anschluss an die Variablendeklarationen kommt der erste Teil des Scriptes. Dieser dient dazu, unsere Kopfzeile zu erstellen und mit den entsprechenden CSS-Klassen auszustatten. Im unteren Teil definieren wir unsere Event-Listener für das Scroll- und Resize-Event.

Die JavaScript-Funktionen

Im weiteren Verlauf erstellen wir drei Funktionen.

Die Funktion resetTableWidth

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

Diese Funktion dient dazu, das Resize-Event abzufangen. In dieser Funktion erstellen wir deswegen unseren Timer. Jedes Mal, wenn die Browserfenstergröße geändert wird, wird diese Funktion aufgerufen. Wir möchten nicht sofort unsere Neuberechnung der Spaltenbreite anstoßen. Es ist möglich, dass die Größe des Browserfenster in wenigen (Milli-)Sekunden noch einmal geändert wird. jetzt die Berechnung durchzuführen, ergäbe keinen Sinn. So sagen wir dem Timer, er soll in einer Sekunde (1000 Millisekunden) eine andere Funktion aufrufen. Sollte in dieser Zeit, die Größe des Browserfensters wieder geändert werden, wird der Timer gestoppt. Die Sekunde beginnt wieder zu laufen. Dies geschieht so lange, bis eine Größenänderung für eine Sekunde nicht mehr eintritt.

Die Funktion updateHeaderTableWidth

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

In dieser Funktion setzen wir die Spaltenbreiten unserer Kopfzeile auf die Breite der Inhaltstabelle. Zudem bekommt unsere Tabelle in der Kopfzeile die selbe Breite wie unsere Inhaltstabelle.

Die Funktion scrolling

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";
	}
}

In der ersten Zeile positionieren wir unsere Kopfzeile so, dass Sie mit den Spalten der Inhaltstabelle übereinstimmt.

Der Rest der Anweisungen kümmert sich darum, die Kopfzeile nur sichtbar zu machen, wenn auch die Tabelle sichtbar ist. Dabei soll die Kopfzeile nur sichtbar sein, wenn noch mindestens eine Inhaltzeile zu sehen ist.

Diese Variante hat einen kleinen Nachteil. JavaScript muss natürlich beim Client aktiviert sein. Bei Mobilgeräten wird dies sehr wahrscheinlich der Fall sein. Auf einem Desktopgerät kann dies aber anders sein, beispielsweise durch eine Erweiterung wie JS Blocker.

Variante 3 mit HTML5 und CSS3

In der Variante 2 wird es sicher passieren, dass die Tabelle nach rechts aus dem Viewport läuft. Der Nutzer eines Smartphones muss wie bei der ersten Variante nach links und rechts scrollen. Wenn dies nicht gewünscht ist, kann die Tabelle für kleine Bildschirmgrößen auch umformartiert werden. Die Tabelle läuft nicht mehr nach rechts, sondern nach unten.

Um dies zu bewerkstelligen, müssen wir unseren HTML-Code für die Tabelle anpassen.

Das HTML der Tabelle anpassen

Dank dem HTML5-Attribut data können wir einem Element beliebigen Inhalt geben, der nicht direkt im Browser sichtbar ist.

Zuerst geben wir jedem tr-Element ein data-mykey-row-Attribut. Wichtig ist nur, dass das Attribut mit data- beginnt. Danach sollte ein Schlüsselwort kommen, dass im besten Fall eindeutig ist. Nutzen Sie andere Scripte, die darauf Bezug nehmen, so kann es andernfalls zu Problemen kommen.

Jedem dieser Attribute geben wir nun einen einmaligen Wert. In unserem Beispiel ist die Zeile 1 das "Objekt 1", die zweite Zeile das "Objekt 2", usw. Für das tr-Element bedeutet dies beispielsweise:

<tr data-mykey-row="Objekt 1"><td></td></tr>

Jedem td-Element geben wir nun ebenfalls solch ein Attribut. Um Zeilen und Spalten auseinander zu halten, nennen wir dieses Attribut data-mykey-column. Der Wert dieses Attributes ist in jeder Spalte (nicht Zeile) identisch. D.h. der Wert dieses Attributes ist für die Spalte 1 in allen Zeilen identisch. Die zweite Spalte (für alle Zeilen) bekommt einen anderen Wert. In unserem Beispiel würde es für zwei Spalten bedeuten:

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

Das CSS für die Tabelle anpassen

Zuerst müssen Sie einen Breakpoint finden. An diesem Punkt (in unserem Beispiel 60em) soll die normale Tabelle für große Bildschirmbreiten in eine vertikale Tabelle für kleine Bildschirmbreiten umbrechen. Wenn Sie den Breakpoint gefunden haben, können Sie folgende CSS-Anweisungen nutzen (vorher 60em durch Ihren Breakpoint austauschen):

@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;}
}

Wir blenden zuerst die Kopfzeile der Inhaltstabelle aus. Diese brauchen wir für eine vertikale Tabelle nicht. Anschließend definieren wir einige Elemente als Block-Elemente. So funktionieren auch padding-Anweisungen.

In den letzten zwei Zeilen kommen nun unsere data-Attribute zum Einsatz.

Zuerst bekommen unsere Spalten Ihren Namen. Nach dem Spaltenname folgt ein Doppelpunkt und ein Leerzeichen. Im Anschluss folgt der Inhalt der Tabellenspalte. Im oberen Beispiel wäre dies Name: Müller.

In der letzten Anweisung bekommt jede Zeile nun Ihren Namen. Oben haben wir dafür "Objekt 1" und "Objekt 2" genutzt.

Zusammenfassung

Wie Sie sehen, gibt es Möglichkeiten, eine Tabelle auch auf kleinen Bildschirmbreiten (halbwegs) darzustellen. Für die Varianten 2 und 3 haben wir hier ein gemeinsames Beispiel. Die obere Tabelle in der Demo zeigt die Variante 2 und die untere Tabelle die Variante 3. Auf Desktop-Geräten ziehen Sie das Browserfenster kleiner oder größer um den Umbruch der zweiten Tabelle in Aktion zu sehen.

Kommentar schreiben

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