Sonntag, 30. August 2009

Das böse Tabellenlayout

Das tabellarisch strukturierte Layout mit Hilfe sogenannter blinder Tabellen ist unter Webdesignern nicht sehr beliebt. Sie empfehlen, statt mit Präsentierungselementen wie dem <table>-Tag möglichst konsequent mit semantischen Elementen zu arbeiten - wie <label>, <fieldset> oder natürlich mit den allgemeineren Platzhaltern <div> und <span>.

Folgende Schwächen des table-basierten Layouts führen beispielsweise Rachel Andrew und Dan Shafer in ihrem CSS-Standardwerk [1] auf:

  • "Tabellen verursachen lange Ladezeiten."- Hier vermisse ich eine Performanceanalyse, die die Rendering Times einer blinden Tabelle mit denen eines Substituts vergleicht, das nur mit semantischen Elementen arbeitet. Ohne selbst eine solche zu kennen, nehme ich gerne die Gegenposition ein, dass für einen modernen Browser die Rendering Times für eine blinde Tabelle ebensowenig ins Gewicht fallen wie ein vergleichbares Präsentierungskonstrukt auf Basis von CSS.

  • "Tabellen pflegen ist ein Alptraum."- Wirklich? Wenn man ein Tabellenlayout nicht bodenlos tief verschachtelt, ist es durchaus möglich, es in lesbarer Form hinzuschreiben. Leider wird auf die Lesbarkeit in dem von HTML-Editoren generiertem Code wenig Wert gelegt. Da ein guter Webdesigner aber sowieso den "mundgeblasenen" HTML-Code bevorzugt und HTML-Editoren meidet wie der Teufel das Weihwasser, sehe ich hier nicht wirklich ein Problem. Auf der anderen Seite verschiebt man Komplexität schliesslich nur, wenn man sie vom HTML-Quelltext in das CSS verlegt: Anordnungen zu ändern, ist so oder so nicht ohne Aufwand zu haben. Dass die Änderungen in einer blinden Tabelle aber so furchtbar ins Gewicht fallen, scheint mir eine propagandistische Übertreibung zu sein.

  • "Tabellen verursachen Probleme mit der Zugänglichkeit."- Es wird beanstandet, dass ein Screen Reader für Blinde die nicht sichtbaren Formatierungselemente einer Tabelle mit liest. Der Blinde bekommt also die für die Visualierung verwendeten Elemente mit zu hören. Ich habe das nicht selbst geprüft, halte es aber, wenn es wirklich so ist, für ein Problem des Screen Readers! Ein solches Programm sollte in der Lage sein, den nur zur Strukturierung der Präsentation verwendeten Code zu erkennen und nicht vorzulesen - es sei denn, die Strukturierung lässt sich auch sprachlich abbilden.


All diese Argumente überzeugen mich also nicht. Das einzige Argument, das ich gelten lassen würde, wäre folgendes:

  • Ein Tabellen-Layout verquickt den Content mit der Präsentierung dieses Contents.- Der Inhalt wird am selben Ort gespeichert wie die Information über seine visuelle Darstellung. Es wäre flexibler, wenn man den Content von der Präsentierung trennen könnte.

    Man könnte hier einwenden, dass wir mit HTML ja sowieso bereits im Präsentierungslayer sind. Aber es zeigt sich häufig, dass auch hier eine Trennung von Inhalt und Präsentierung noch sinnvoll ist. Das HTML-Dokument wird lesbarer, klarer, wenn die Aufbereitung der Information ins Stylesheet ausgelagert wird. Auch lässt sich das Stylesheet für andere, ähnliche HTML-Dokumente wiederverwenden.


Wenn CSS im heutigen Stand diese Trennung ermöglicht, wäre ich der erste, sie zu nutzen! Leider ist das, soweit ich das übersehen kann, noch nicht der Fall.

Um dies zu demonstrieren, werde ich einmal konkret und stelle eine ganz einfache, elementare Übungsaufgabe an den Webdesigner - so als ob man den Rennfahrer fragen würde, ob er Gas geben kann. Der Designer möge bitte ein Formular wie das folgende zur Eingabe von Name, Vorname und E-Mail-Adresse entwerfen:




Mit Table-Elementen hat man das Formular schnell hingeschrieben, es könnte zum Beispiel so aussehen:


<table id="adresse">
<caption>Adressdaten</caption>
<tr>
<td class="label">Name</td>
<td><input type="text" name="name"/></td>
</tr>
<tr>
<td class="label">Vorname</td>
<td><input type="text" name="vorname"/></td>
</tr>
<tr>
<td class="label">E-Mail-Adresse</td>
<td><input type="text" name="email"/></td>
</tr>
</table>

Hierdurch wird also festgelegt, dass die Eingabefelder alle bündig untereinander erscheinen sollen, und ebenso deren Bezeichner. Umbrüche werden durch den Wechsel zu einer neuen Tabellenzeile gesteuert.

Dieser Code vermischt tatsächlich Präsentierung mit Content: Welche Felder in welcher Zeile erscheinen, ist statisch im Code festgelegt und damit nicht vom eigentlichen Seiteninhalt getrennt. Das ist sicher nicht schön. Schöner wäre ein Code mit semantischen Elementen, wie der folgende:

<fieldset id="adresse">
<legend>Adressdaten</legend>
<label for="name">Name</label>
<input type="text" id="name"/>
<label for="vorname">Vorname</label>
<input type="text" id="vorname"/>
<label for="email">E-Mail-Adresse</label>
<input type="text" id="email"/>
</fieldset>

Hier haben wir wirklich nur Content, und darüberhinaus werden auch die Elementnamen wie label und fieldset eingesetzt, um die Semantik des Contents zu beschreiben. Für den Zugriff im Stylesheet (und im JavaScript) gibt es neben dem Elementnamen noch eine ID. Mehr steht hier nicht: Keine Umbrüche, kein Alignment.[2]

Aber: Probieren Sie einmal, das heute verwendbare CSS2 zu benutzen, damit der obige HTML-Code wie in der Graphik dargestellt erscheint. Eine einfache Übung, finden Sie? Wohlgemerkt, ohne dem obigen <fieldset>-Codefragment weiteren HTML-Code hinzuzufügen: Keine Hilfselemente wie <p/> oder <br/>, um einen Umbruch zu erzwingen (reine Präsentierung, das muss doch im CSS gehen!), keine "Wrapper"-Divs oder ähnliche Kunstgriffe. Das sind alles nur Hacks für die Präsentierung, die im Content nichts zu suchen haben! Wer einen Wrapper-Div einführen muss, nur damit er seine Präsentierung mit CSS wie gewünscht hinbekommt - also ohne dass der Content dies erfordert - macht schliesslich nichts anderes als seine Vorgänger, die das böse transparent.gif einsetzten!

Und wir finden solche reinen Präsentierungs-Divs bei den CSS-Meistern jeden Ranges im Web. Da wird ganz unbefangen ein
  <div class="clear"/>
verwendet, nur weil es in der Sprache CSS ohne einen solchen Div nicht möglich ist zu sagen, dass drei aufeinanderfolgende Elemente in einer Zeile angeordnet werden, danach aber eine neue Zeile begonnen werden soll: Die drei Elemente muss man mit float:left formatieren, und die so gesetzte Flussrichtung muss mit clear:both wieder zurückgesetzt werden (das der obigen CSS-Klasse clear zugeordnet wäre). Was für eine wunderbare Trennung von Content und Präsentierung!

Ich will damit nur sagen: In der jetzigen Form finde ich CSS nicht ausgereift und nicht appetitlich genug, um den Präsentierungslayer vollständig zu übernehmen. Und solange das noch so ist, bin ich in manchen Fällen (wie dem obigen) mit dem Tabellenlayout schneller, ohne irgendwelche Nachteile gegenüber einer CSS2-Lösung zu haben. In zukünftigen CSS-Versionen mag sich das ändern.

Warum aber eigentlich nicht gleich ein XSL-Stylesheet schreiben, das den folgenden Content verarbeitet und wie gewünscht im Browser rendert:
<z:fieldset legend="Adressdaten">
<z:input name="name">Name<z:input>
<z:input name="vorname">Vorname</z:input>
<z:input name="email">E-Mail-Adresse</z:input>
</z:fieldset>

Diese neu definierten Elemente erlauben eine totale Reduktion des Dokuments auf die semantische Ebene. Die Präsentierung greift in Form eines XSLT-Programms auf den Content zu und bereitet ihn auf. Ein solches XSL-Stylesheet kann zum Beispiel die Feldgruppe in Form eines Tabellenlayouts rendern. Wenn CSS dann einmal soweit ist, dass einfache Aufgaben wie diese auch mit einfachen Mitteln gelöst werden können, muss nur das XSL-Stylesheet angepasst werden, nicht jedoch das Dokument, das den Content enthält.

XSLT-Prozessoren sind in allen Browsern längst auf einem so guten Stand, dass es kein Problem mehr darstellt, solche Elemente on-the-fly im Browser in (X)HTML zu konvertieren. Wo dies - bei komplexeren Seiten - doch ein Performanceproblem darstellen sollte, kann man die Transformation auch - wo es sinnvoll ist, gepuffert - auf dem Server ausführen. Und der Content ist auf diese Weise wirklich vollständig vom Layout getrennt.


[1] Rachel Andrew, Dan Shafer: CSS – Anspruchsvolle Websites mit Cascading Stylesheets. 2. Auflage, dpunkt Verlag, Heidelberg 2006.
[2] Allerdings gibt es eine Anordnung: Name kommt vor Vorname, und der vor der E-Mail-Adresse. Ändert man die Anordnung im HTML-Quelltext, resultiert dies in der Regel auch in einer geänderten Darstellung (wenn nicht alle Elemente via ID absolut positioniert werden). Damit stellt auch die Anordnung in den meisten Fällen eine präsentierungsrelevante Information dar.

Kommentare :

Sanníe hat gesagt…

Auf die Schnelle, aber das geht sicher auch eleganter.

fieldset {background: #f7f7f7; font: normal 11px sans-serif; width: 350px; border: none; padding: 5px;}
legend {font-style: italic;}
label {background: #cecece; width: 51%; display: block; float: left; font-weight: bold; text-align: right; border-bottom: 0.2em solid #cecece; line-height: 20px; padding-right: 2px; border-bottom: 2px solid #f7f7f7;}
input {display: block; float: right; width: 46%; line-height: 20px;}

Rüdiger Plantiko hat gesagt…

Hallo Sannie,

schöne Lösung! Du hast die Rennfahrerprüfung bestanden :-)

Als ich diesen Blog schrieb, hatte ich diese Lösung nicht gesehen (ich hatte lange probiert). Die wesentliche Idee Deiner Lösung scheint das "display:block" für die Labels und Eingabefeldern zu sein.

OK, also es geht - danke für den Beitrag!

Gruss,
Rüdiger