CSS Float Float

#: Die Aufgabe

Eines schönen Sonntag mittag begab es sich, dass mir für eine Website eine bestimmte Formatierung eines Eintrag-Kopfes vorschwebte. Die Headline, rechtsbündig und da drunter, in einer Zeile, linksbündig das Datum und rechtsbündig die Kategorie des Eintrages. Siehe auch die untenstehende Abbildung.

Der Eintrag-Kopf: Headline, dadrunter Datum und Kategorie
Die Herausforderung bestand darin, sowas in CSS umzusetzen. Einen quicken Hack habe ich mir binnen zwei Minuten aus den Fingern gesogen, bevor ich die Wohnung verlassen musste.
.container { line-height: 0px; }
.links { text-align: left; }
.rechts { text-align: right;}
<div class="container">
   <div class="links">Datum<div>
   <div class="rechts">Kategorie<div>
</div>
Man kann hier eher von einem CSS-Mißbrauch sprechen. Ich lege Datum und Kategorie in zwei Zeilen ab, die aber scheinbar auf der gleichen Zeilenhöhe sind, da der Zeilenabstand von mir, via line-height auf Null gesetzt wurde.
Da ich sowieso weg musste, gab ich die Frage in dogfood raus: wie kann man es eleganter machen. Und es gab auf die Frage dann doch so regen Zuspruch, dass ich mich gezwungen sah, dieses Thema ausführlicher abzufrühstücken.
Die Einsendungen liessen sich grob in zwei Ansätze unterteilen. Die beiden Ansätze lassen sich in Aktion auf einer Beispielseite betrachten.

#: Lösung 1: Single float


Der normale Seitenfluß
Dieser Ansatz wurde mir von Katharina Fedtke, Ulf Tiburtius, Stefan Freimark, Michael Preidel und Connie Sell zugeschickt. Ohne es abwertend zu meinen, handelt es sich um die konventionellere Methode.
Der Inhalt einer HTML-Seite ist durch die HTML-Tags in Blocks untergliedert. In der Regel stellt ein Browser auf einer Seite untereinander Block für Block dar. Der normale "Seitenfluß" halt.
Der "Single-Float"-Ansatz nimmt nun den Block mit dem Datum durch den Befehl float: left; aus dem normalen Seitenfluß raus (Abb.2).

Abb.2: Seitenfluß um den float-Block herum
Simpel gesagt, bewirkt die CSS-Eigenschaft float, dass der betreffende Block links (float: left;) oder rechts (float: right;) an den Rand positioniert wird und dort "Platz blockiert". Die Besonderheit von float liegt nun im Verhalten des nächsten Blockes, der nicht unterhalb des float-Blockes beginnt, sondern bereits auf gleicher Höhe neben dem float seinen Platz sucht und den verbleibenden Platz auffüllt! Der zweite Block versucht also um den ersten Block herumzufliessen, daher der Name der CSS-Eigenschaft float.
Auf unser Beispiel übertragen: Das Datum wird als float an den linken Rand gesetzt. Der nächste Block ist die Kategorie. Diese beginnt auf gleicher Höhe wie das "gefloatete" Datum, wird aber per text-align: right; rechtsbündig an den Rand gesetzt.
<div style="float: left">Datum</div>
<div style="text-align: right;">Kategorie</div>
<div>Weiter im Fliesstext. Blablabla</div>

#: Lösung 2: float-float

Dieser Ansatz wurde mir von Dennis Frank, Sebastian Werner und Gerrit Kaiser eingesandt. Ich habe für diesen Ansatz höchste Sympathien, da ich ihn semantisch korrekter als Lösung 1 finde.

Abb.3: Zwei Floats
Der Ansatz von Lösung 1 ist im Grunde genommen: "wir haben Text und nehmen das Datum als float aus dem normalen Seitenfluß raus und kleben ihn nach links an den Rand". Es stellt sich aber die Frage: warum das Datum und nicht die Kategorie, bzw. warum wird die Kategorie wie normaler Text behandelt?
Der Punkt ist: eigentlich sollten sowohl Datum als auch Kategorie gesondert behandelt werden. Es liegt also in der Logik der Dinge beide als float zu setzen. Eines links, eines rechts.
<div style="float: left;">Datum</div>
<div style="float: right;">Kategorie</div>
<div style="clear: both;">Weiter im Fliesstext. Blablabla</div>
Eine wichtige Rolle kommt dem clear:both; zu. Ohne dem clear würde der Fliesstext-Block versuchen in der Mitte zwischen den beiden Floats zu beginnen. clear heißt also soviel: "starte den Block unterhalb aller Blocks, inkl. der floats". Siehe die offiziöse und umfangreichere Erklärung der W3C-Specs.
Ein weiterer Unterschied fällt gegenüber der ersten Lösung auf. Wenn auf den Fliesstext ein margin-top angewandt wird, um für einen Abstand nach oben zu sorgen, so wird dieser anders bemessen. Bei der ersten Lösung wird der Abstand vom Ende des Blocks "Kategorie" an gerechnet. Bei dieser Lösung werden die float-Blocks für die Berechnung des Abstandes ignoriert. Stattdessen wird der Block dadrüber, also die Headline genommen.
Wie gesagt: ich halte dies für die semantisch sauberere Lösung (= logischere Gliederung der HTML-Seite). Allerdings halte ich Layouts mit zwei Floats, wohlmöglich auch noch innerhalb eines komplexeren Layouts, für recht fragil, angesichts der langen Liste an Browser-Macken und Empfindlichkeiten. Die Lösung ist deshalb mit Vorsicht zu geniessen und Umsetzungen sollten ausgiebig getestet werden.
Eric Meyer hat gereade zur richtigen Zeit einen Text geschrieben ("Containing Floats"), der einige Prinzipien beim Handling von Floats beschreibt, u.a. einen interessanten "Floats-in-Floats"-Trick zeigt.
Ich möchte mich nochmals bei allen bedanken die geschrieben haben: Sebastian Werner, Michael Preidel, Gerrit Kaiser, Ulf Tiburtius, Stefan Freimark, Connie 'nennt mich nicht Cornelia' Sell, Katharina Fedtke und Dennis Frank.
dogfood, 30.August 2003