Dieser Text wurde ursprünglich von Noah Stokes in A List Apart, Ausgabe 325, in englischer Sprache unter dem Titel „CSS floats 101“ veröffentlicht.
Translated with the permission of A List Apart Magazine and the author[s].
Die Float-Eigenschaft ist eine wertvolle und wirksame Bereicherung für jeden Webdesigner/-entwickler, der mit HTML und CSS arbeitet. Tragischerweise kann sie auch Frust und Verwirrung stiften, wenn nicht gänzlich verstanden wird, wie sie funktioniert. Zudem hingen mit ihr in der Vergangenheit einige ziemlich fiese Browser-Bugs zusammen, es ist also normal, wenn man beim Gebrauch der Float-Eigenschaft in den CSS-Regeln nervös wird. Beruhigen wir diese Nerven und lindern wir diesen Frust. Ich werde Ihnen genau zeigen, was die Float-Eigenschaft mit Ihren Elementen macht und wie unglaublich nützlich sie eingesetzt werden kann, wenn sie erst einmal beherrscht wird.
„Floats“ begegnen uns in Druckerzeugnissen jedes Mal, wenn wir uns einen Zeitungsartikel ansehen, in dem der Text um ein links oder rechts befindliches Bild schön herumfließt. In der Welt von HTML/CSS umfließt ein Text ein Bild, auf das die Float-Eigenschaft angewendet wurde, ähnlich wie im Zeitungslayout. Bilder sind nur eine der vielfältigen Anwendungsfälle für die Float-Eigenschaft: Auch das beliebte zweispaltige Layout kann mit Hilfe von Floats erreicht werden. Man kann in der Tat so gut wie jedes HTML-Element floaten. Nachdem Sie die Grundlagen der Float-Eigenschaft, zusammen mit den Grundlagen der Positionierungseigenschaften (deutsch), gelernt und verstanden haben, werden Sie zuversichtlich jedes Layout gestalten können.
Wir beginnen mit der Definition von Float laut dem W3C:
Ein Float ist eine Box, die auf der aktuellen Zeile nach links oder rechts verschoben wird. Die interessanteste Eigenschaft eines Floats (oder einer „gefloateten“ oder „floatenden“ Box) besteht darin, dass Inhalte an seinen Rändern entlang fließen können (oder mittels der „clear“-Eigenschaft daran gehindert werden können). Inhalte fließen entlang der rechten Seite einer links gefloateten Box und entlang der rechten Seite einer links gefloateten Box. [Übers. AH]
Der Float-Eigenschaft können vier Werte zugewiesen werden: left, right, inherit und none. Die einzelnen Werte erklären sich von selbst. Zum Beispiel wird das Element, dem float: left zugeordnet wird, zur linken Grenze des Eltern-Elements bewegt. Dasselbe Prinzip gilt für die Zuordnung von float: right. Dieses Element würde zur rechten Grenze des Eltern-Elements geschoben werden. Der Wert inherit sorgt dafür, dass der Float-Wert des Eltern-Elements übernommen wird. Der Wert none ist der Standardwert und sorgt dafür, dass das Element überhaupt nicht floatet.
Hier ein einfaches Beispiel A wie in der oben erwähnten Zeitung und der zugehörige Code:
img {
float: right;
margin: 10px;
}
Nichts besonders Komplexes und doch ziemlich cool, oder? Ein Kinderspiel, sagen Sie? Nun gut, bevor wir so weit gehen, dass Floats in eine Welt voller speckverliebter Einhörner führen, wollen wir einen Schritt zurückgehen und darüber reden, was hier tatsächlich passiert. In der Netzwelt ist unser HTML an einige Regeln gebunden, insbesondere an den Normalfluss. Im Normalfluss wird jedes Blockelement (div, p, h1 usw.) vertikal auf das nächste gesetzt, von oben im Ansichtsfenster nach unten. Gefloatete Elemente werden zuerst gemäß dem Normalfluss aufgebaut, dann aus diesem Fluss genommen und so weit nach rechts oder links (abhänging vom angewendeten Wert) geschoben, wie das Eltern-Element es zulässt. In anderen Worten: Sie liegen nicht mehr übereinandern, sondern nebeneinander, vorausgesetzt, es gibt im Eltern-Element für jedes gefloatete Element ausreichend Platz. Dieses Verhalten muss notwendigerweise für das Bauen von Websites im Gedächtnis behalten werden.
Sehen wir uns ein paar weitere Beispiele an. In Beispiel B stehen drei Blöcke ohne Float:
.block {
width: 200px;
height: 200px;
}
Sehen Sie, wie die Blöcke übereinander gestapelt liegen? Das ist das Grundkonzept des Normalflusses. Hier noch einmal das gleiche Beispiel, nur dass dieses Mal alle Blöcke gefloatet sind. Beispiel C:
.block {
float: left;
width: 200px;
height: 200px;
}
Nun liegen die Blöcke Seite an Seite. Großartig, das hätten wir. Aber was wird nun aus dem Teil, den ich erwähnt habe, „vorausgesetzt, es gibt im Eltern-Element für jedes gefloatete Element ausreichend Platz“? Ich dachte schon, Sie fragen nicht mehr. Nehmen wir das letzte Beispiel und verfünffachen die Anzahl der Blöcke. Das Eltern-Element ist in diesem Beispiel der Body, also der gesamte anzuzeigende Inhalt, unseres Dokuments. Sie sehen, dass in Abhängigkeit von der Größe Ihres Browserfensters (und folglich des Eltern-Elements body) die Blöcke in die zweite Reihe rutschen, weil nicht genug Platz ist, um alle nebeneinander in einer Reihe anzuordnen. Wenn Sie die Größe des Browserfensters so verändern, dass mehr Platz entsteht, sehen Sie, dass die Blöcke sich selbst neu anordnen. Probieren Sie es in Beispiel D selbst aus.
clear-FunktionDie Eigenschaft float hat einen Stiefbruder, clear. Die beiden ergänzen sich gegenseitig auf eine Weise, die Sie zu einem glücklichen Webdesigner machen sollten. Wie Sie sich vielleicht erinnern, wird ein gefloatetes Element erst gemäß Normalfluss ausgerichtet und dann von diesem Normalfluss entfernt. Dies bedeutet, dass jedes Element, das einem gefloateten Element folgt, sich genau gegenteilig zu dem verhalten wird, was Sie erwarten. Hier könnten wir, vermute ich, Schwierigkeiten bekommen. Lassen Sie uns kurz ein weiteres Beispiel mit unseren Blöcken ansehen. In Beispiel E werde ich zwei Blöcke (pink und blau) floaten und sofort danach zwei weitere Blöcke (grün und orange) nicht floaten. Es folgen die HTML- und CSS-Codes für Beispiel E:
<div class="block pink float"></div>
<div class="block blue float"></div>
<div class="block green"></div>
<div class="block orange"></div>
.block {
width: 200px;
height: 200px;
}
.float { float: left; }
.pink { background: #ee3e64; }
.blue { background: #44accf; }
.green { background: #b7d84b; }
.orange { background: #E2A741; }
Wie gefällt Ihnen der grüne Block? Halt, wo ist er? Er ist gleich unter dem pinken Block. Der pinke und der blaue Block sind beide gefloatet und verhalten sich, wie wir erwarten würden, sie liegen nebeneinander. Da sie jedoch vom Normalfluss entfernt wurden, verhalten sich der grüne und orangefarbene Block so, als gäbe es sie gar nicht erst. Deshalb ist unser grüner Block unter dem pinken Block versteckt. Wie lassen wir den grünen Block nun wieder auftauchen? Geben Sie die Eigenschaft clear ein.
Die Eigenschaft clear verfügt über fünf Werte: left, right, both, inherit und none. Gibt man den Wert left ein, bedeutet dies, dass die obere Kante des Elements unter jedem Element angeordnet sein muss, auf das die Eigenschaft float: left angewendet wird. Dasselbe Konzept gilt für den Wert right: Das Element muss unter jedem Element angeordnet sein, auf das die Eigenschaft float: right angewendet wird. Indem man den Wert both verwendet, muss die obere Kante unseres Elements unter jedem - sowohl links als auch rechts - gefloateten Element angeordnet sein. Der Wert inherit übernimmt den clear-Wert seines Eltern-Elements, während der Standardwert none sich so verhält, wie man es erwarten würde. Mit diesem Wissen sind wir für Beispiel E2 gerüstet. Diesmal clearen wir unsere zwei Floats, indem wir die Eigenschaft clear auf unseren grünen Block anwenden. Unser leicht abgeänderter Code sieht wie folgt aus:
<div class="block pink float"></div>
<div class="block blue float"></div>
<div class="block green clear"></div>
<div class="block orange"></div>
.block {
width: 200px;
height: 200px;
}
.float { float: left; }
.clear { clear: left; }
.pink { background: #ee3e64; }
.blue { background: #44accf; }
.green { background: #b7d84b; }
.orange { background: #E2A741; }
Indem wir unserem grünen Block eine Eigenschaft clear: left zuordnen, sagen wir ihm, dass er sich so verhalten soll, als wäre der pinke Block im Normalfluss unseres Dokuments, obwohl er daraus entfernt wurde. Er soll also unter ihm angeordnet sein. Dies ist eine immens wirkungsvolle Eigenschaft; wie Sie sehen, verhilft es unseren nicht gefloateten Elementen zurück in den Normalfluss, ein Verhalten, das wir tendenziell als Standard erwarten. Abgesehen davon öffnet die Kenntnis und das Verständnis der Eigenschaften float und clear einige Tore zur Kreativität, wenn Sie in HTML und CSS schreiben.
Behandeln wir nun Layouts. Hier ist die Eigenschaft float unglaublich nützlich. Wir können das traditionelle zweispaltige Layout auf eine Vielzahl von Arten erreichen; die meisten davon gebrauchen ein oder zwei gefloatete Elemente. Sehen wir uns ein einfaches Beispiel an: Eine zweispaltige Website mit dem Inhaltsbereich auf der linken Seite, der Navigation auf der rechten, dazu einen Kopf und eine Fußzeile, um es abzuschließen. Für diesen Artikel beschränken wir uns darauf, den Code für die gefloateten Elemente anzusehen. Hier ist Beispiel F:
#container {
width: 960px;
margin: 0 auto;
}
#content {
float: left;
width: 660px;
background: #fff;
}
#navigation {
float: right;
width: 300px;
background: #eee;
}
#footer {
clear: both;
background: #aaa;
padding: 10px;
}
Nun lassen Sie uns darüber reden, was hier geschieht. Unser beinhaltendes Eltern-Element wird passenderweise #container genannt. Es hält unsere gefloateten Elemente in einem bestimmten Raum. Hätten wir dieses Element nicht, würden unsere gefloateten Elemente an die äußersten linken und rechten Ränder unseres Sichtbereiches (unseres Browserfensters) geschoben werden. Als nächstes haben wir #content und dann #navigation. Dies sind unsere gefloateten Elemente. Wir haben #content nach links geschickt und #navigation nach rechts, um unser zweispaltiges Layout zu erreichen. Ich habe für jedes eine Breite definiert, sodass sie den gesamten Eltern-Container füllen. Schließlich gibt es den #footer, für den wir die Eigenschaft clear anwenden. Wie wir aus dem Vorangegangenen wissen, bringt diese Eigenschaft clear die Elemente, die einem gefloateten Element folgen, zurück in den Normalfluss. In diesem Fall besitzt der #footer den Wert both, was dazu führt, dass unser #footer unterhalb der Elemente #content und #navigation angeordnet ist.
Was wäre passiert, hätten wir vergessen, die Eigenschaft clear auf unsere Fußzeile anzuwenden? Sehen Sie sich Beispiel G an.
Unser #footer ist unter das Element #navigation gerutscht. Das passiert, weil unterhalb von #navigation freier Platz ist, den #footer ausfüllen kann, und im Falle des Normalflusses, in dem wir arbeiten, ist dies auch tatsächlich das korrekte Verhalten. Aber das ist definitiv nicht, wonach wir suchen, oder? Sie beginnen nun also, das Zusammenspiel der Eigenschaften float und clear zu verstehen und warum beide einander so gut ergänzen.
Wenn Sie ein obsessives Zwangsverhalten haben, so wie ich, dann werden Sie feststellen, dass es in Beispiel F ungleiche Höhen für #content und #navigation gibt; es gibt mehrere Arten, diesen Sachverhalt anzusprechen, aber das liegt außerhalb der Zielstellung dieses Artikels. Ich empfehle wärmstens die Lektüre von Faux Columns von Dan Cederholm (deutsch), um zu lernen, wie die Höhen so eingestellt werden können, dass sie unabhängig vom Inhalt gleichmäßig aussehen.
Bislang haben wir ein paar ziemlich einfache Beispiele gesehen, die nicht sonderlich Kopfschmerz verursachen. Es gibt jedoch einige häufige Fehler, auf die geachtet werden muss, wenn mit der Float-Eigenschaft gearbeitet wird. Überraschenderweise liegt einer der größten dieser Fehler nicht im CSS, sondern eher im HTML selbst. Abhängig von der Stelle, an der Sie ein gefloatetes Element in Ihrem HTML anordnen, kann ein anderes Ergebnis herauskommen. Sehen Sie sich Beispiel H an.
Wir haben hier einen netten kleinen Block, der ein rechts floatendes Bild beinhaltet und etwas umgebenden Text. Unser CSS ist einfach:
#container {
width: 280px;
margin: 0 auto;
padding: 10px;
background: #aaa;
border: 1px solid #999;
}
img {
float: right;
}
Unser Eltern-Element, #container besitzt eine geringe Breite, die unser gefloatetes Element, img, in Grenzen hält. Unser HTML sieht wie folgt aus:
<div id="container">
<img src="image.gif" />
<p>This is some text contained within a
small-ish box. I'm using it as an example
of how placing your floated elements in different
orders in your HTML can affect ayour layouts. For
example, take a look at this great photo
placeholder that should be sitting on the right.</p>
</div>
Dieses grundlegende Konzept liefert uns das gewünschte Ergebnis, aber was passiert, wenn wir das gleiche Beispiel nehmen und das HTML nur leicht verändern? In Beispiel I verschieben wir img so, dass es nach unserem Textabschnitt steht:
<div id="container">
<p>This is some text contained within a
small-ish box. I'm using it as an example
of how placing your floated elements in different
orders in your HTML can affect your layouts. For
example, take a look at this great photo
placeholder that should be sitting on the right.</p>
<img src="image.gif" />
</div>
Unser Ergebnis ist weniger als wünschenswert. Unser Bild wird rechts gefloatet, aber es befindet sich nicht mehr in der oberen Ecke, wo wir es haben wollten, sondern rutscht unter unseren Absatz; schlimmer noch, es scheint aus dem unteren Ende unseres Eltern-Elements #container herauszuragen. Was ist hier los? Erstens habe ich eine Regel gefunden, die für meine Layouts gut funktioniert: zuerst floaten. Das heißt, dass ich in meinem HTML fast immer zuerst die gefloateten Elemente in den Markup-Code eingebe, vor jedem nicht gefloateten Element, mit dem mein Float zusammenspielen wird, wie der Textabsatz im obigen Beispiel. Meist wird so das gewünschte Ergebnis erreicht. Zweitens hat die Tatsache, dass das Bild anscheinend aus dem unteren Ende des #container-Elements herausragt, mit einem Verhalten zu tun, das Zusammenfallen bzw. Collapsing genannt wird. Reden wir darüber, was Collapsing ist und wie damit am besten umgegangen werden kann.
Der Begriff Collapsing wird verwendet, wenn ein Eltern-Element, das irgendeine Anzahl von gefloateten Elementen beinhaltet, sich nicht so weit ausdehnt, um alle Elemente zu umgeben, so wie es immer geschehen würde, wenn alle Elemente nicht gefloatet wären. Im obigen Beispiel I fiel unser Eltern-Element #container zusammen, als wäre das gefloatete Element img nicht einmal da. Das ist kein Browser-Bug, sondern eher ein erwartetes und richtiges Verhalten. Da gefloatete Elemente ursprünglich im Normalfluss berechnet und dann entfernt wurden, versteht das Element #container es nicht als zu seinem Bereich zugehörig und verhält sich deshalb so, als wäre es nicht einmal da. Als Randbemerkung: Eric Meyer hat einen wunderbaren Artikel zu diesem Thema geschrieben, Containing Floats, der viel mehr noch in die Tiefe geht und eine höchst nützliche Quelle ist. Die gute Nachricht ist, dass wir dieses Problem auf unendlich viele Arten lösen können; wenn Sie jetzt raten, dass es mit der Eigenschaft clear zu tun haben muss, sind Sie auf dem richtigen Weg.
Eine der üblichsten Möglichkeiten, ein zusammengefallenes Eltern-Element zu reparieren, besteht darin, ein Element mit der Eigenschaft clear nach unserem gefloateten Element einzufügen. Dies wird dazu führen, dass das Eltern-Element nach dem gefloateten Element weiter besteht. Es mag einfacher sein, dies in der Umsetzung zu zeigen. Sehen Sie sich den HTML-Code für Beispiel J an, der der gleiche ist wie in unserem vorangehenden Beispiel, aber mit einem zusätzlichen Element:
<div id="container">
<p>This is some text contained within a
small-ish box. I'm using it as an example
of how placing your floated elements in different
orders in your HTML can affect your layouts. For
example, take a look at this great photo
placeholder that should be sitting on the right.</p>
<img src="image.gif" />
<div style="clear: right;"></div>
</div>
Indem wir div mit einem eigens für dieses Element festgelegten Stil clear: right versehen haben, ermöglichen wir, dass der #container unser gefloatetes Bild cleart, indem er seine Höhe angesichts des unter dem Bild befindlichen Elements neu berechnet. Obgleich diese Lösung funktioniert, ist sie wohl nicht die eleganteste, weil wir zusätzlichen Markup-Code in unser Dokument einfügen mussten. Es wäre sexyer, das mit CSS zu handhaben. Es gibt ein paar Möglichkeiten, das zu tun, also sehen wir uns eine davon gleich an.
Beachten Sie dieses Beispiel, ein Eltern-Element, das drei gefloatete Bilder beinhaltet. Unser HTML-Code sieht folgendermaßen aus:
<div id="container">
<img src="image.gif" />
<img src="image.gif" />
<img src="image.gif" />
</div>
und so unser CSS-Code:
#container {
width: 260px;
margin: 0 auto;
padding: 10px 0 10px 10px;
background: #aaa;
border: 1px solid #999;
}
img {
float: left;
margin: 0 5px 0 0;
}
Wenn Sie sich dies umgesetzt anschauen, werden Sie schnell feststellen, dass unser Eltern-Element nicht unsere gefloateten Bilder beinhaltet. Noch einmal, dieses Verhalten ist zu erwarten, weil gefloatete Elemente aus dem Fluss entfernt werden, für unser Eltern-Element #container gilt also: Es ist leer. Sehen Sie sich dies in Beispiel K an.
Jetzt versuchen wir, dem Abhilfe zu verschaffen, indem wir CSS verwenden, statt zusätzliches HTML-Markup in unser Dokument einzufügen, wie wir es zuvor getan haben. Es gibt eine Methode, die es einem Eltern-Element ermöglicht, sich selbst von allen gefloateten Elementen innerhalb seiner selbst zu clearen. Dabei wird die CSS-Eigenschaft overflow mit dem Wert hidden verwendet. Beachten Sie, dass die Eigenschaft overflow nicht für diese Art Verwendung gedacht ist und Probleme schaffen könnte wie das Verbergen von Inhalt oder das Auftauchen von unerwünschten Scrollleisten. Sie können hier und hier mehr darüber lesen, wie es zu dieser Eigenschaft kam und welche Fallstricke es gibt. Für unser Beispiel werden wir jedoch die Eigenschaft overflow: hidden auf unser Eltern-Element #container anwenden:
#container {
overflow: hidden;
width: 260px;
margin: 0 auto;
padding: 10px 0 10px 10px;
background: #aaa;
border: 1px solid #999;
}
Unsere Ergebnisse befinden sich in Beispiel L. Ziemlich cool, oder? Eine andere Methode, die ein ähnliches Ergebnis mit weniger Fallstricken liefert, verwendet den Pseudoselektor :after. Für unser Beispiel ist der Code wie folgt:
#container:after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
Hier stellt das CSS ein neues Element nach unser Element #container, das Inhalt besitzt (in diesem Fall einen Punkt) und so definiert wird, dass es ohne Höhe versteckt wird. Sie können einen sehr umfassenden und detaillierten Überblick über diese Technik auf Position is Everything finden.
Eric Meyer erklärt in seinem oben bereits aufgeführten Artikel Containing Floats schließlich eine dritte Möglichkeit, dieses Problem zu beheben. Laut der CSS Spec 2.1
wird sich ein gefloatetes Element ausdehnen, um jegliche ihm untergeordneten gefloateten Elemente zu beinhalten.
(a floated element will expand to contain any floated elements that descend from it. [Übers. AH])
In diesem Fall würde also das Floaten unseres Container-Elements dafür sorgen, dass es unser Bild und unseren Absatz genauso beinhaltet wie bei den oben beschriebenen Methoden.
Letztlich machen all diese Lösungen dasselbe. Sie sorgen dafür, dass das Eltern-Element den Fluss ihrer gefloateten Kinder respektiert. Jede hat ihre Verdienste und ihre Nützlichkeit. Sie sollten sich über jede informieren und dann diejenige anwenden, die in Ihrer gegebenen Situation am besten funktioniert.
Glauben Sie es oder nicht, aber es gibt ein paar Browser-Bugs, die gefloatete Elemente mit sich bringen, wie zum Beispiel den double margin bug („Doppelrand-Bug“) und den 3px Text-Jog. Beide stehen nicht im Fokus dieses Artikels, aber ich versichere Ihnen, dass beide leicht zu umgehen sind, wenn Sie auch ältere Browser unterstützen wollen.
Die Verwendung der Eigenschaft float kann die Werkzeugkiste Ihrer Layouttechnik auf eine sehr coole und ansprechende Weise ausschmücken. Das Verständnis ihres Funktionierens und der Prinzipien, nach denen sie sich verhält, wird Ihnen eine solide Grundlage für das effektive Verwenden von Floats verleihen.
© 2012
André Hansen - Übersetzungen
Schmiedeweg 10, D-14641 Nauen
Tel.: +49 33239 71100
E-Mail: andrehansen.ah@googlemail.com