Abschnitt 8 · Lektion 1
Der normale Fluss
Bevor es um Positionierung geht, lohnt ein Blick auf das, was der Browser ganz von allein tut. Denn dieses Verhalten hat einen Namen, und ohne den Namen kann man nicht sagen, was „aus dem Fluss nehmen” eigentlich bedeutet.
Der normale Fluss ist die Anordnung, die entsteht, wenn niemand etwas anderes verlangt. Er trägt praktisch jede Seite, die du je gesehen hast, und die meisten Layout-Probleme lösen sich, indem man ihn machen lässt.
Zwei Sorten Kästen
<div class="block">Ein Block</div>
<div class="block">Noch ein Block</div>
<p>
<span class="inline">Ein Inline-Element</span>
<span class="inline">und noch eins</span>
fließen in derselben Zeile weiter.
</p> body {
font-family: system-ui, sans-serif;
}
/* Blöcke nehmen die volle Breite und stapeln sich,
auch wenn nur ein Wort darin steht. */
.block {
background-color: #dbeafe;
margin-bottom: 8px;
}
/* Vier Angaben an einem Inline-Element, und nur eine
davon wirkt: Breite, Höhe und der senkrechte Abstand
werden ignoriert, die Farbe kommt an. */
.inline {
background-color: #fef9c3;
width: 300px;
height: 80px;
margin-top: 40px;
} Block-Elemente stapeln sich von oben nach unten und nehmen die volle verfügbare Breite. Überschriften, Absätze, div, section, Listen: alles Blöcke.
Inline-Elemente fließen wie Wörter in der Zeile weiter und brechen mit ihr um. span, a, strong, em.
Der zweite Kasten im Beispiel zeigt die Stelle, an der Anfänger zuverlässig stolpern: an einem Inline-Element wirken Breite, Höhe und senkrechte Außenabstände nicht. Man schreibt sie hin, es passiert nichts, und man verdächtigt den Selektor. Der Grund ist der Fluss selbst: eine Zeile lässt sich nicht von einem einzelnen Wort auseinanderdrücken, sonst wäre der Zeilenabstand nirgends mehr verlässlich.
Das ist die erste Stelle im Kurs, an der der Auskunftsstreifen zwei verschiedene Wahrheiten nebeneinanderstellt, und es lohnt sich, kurz hinzusehen. Zeig mit dem Inspector auf das gelbe Inline-Element: Im Reiter „Werte” steht width: 300px, height: 80px und margin: 40px 0px 0px, also genau das, was du geschrieben hast. Ganz oben im Streifen steht neben dem Elementnamen das gemessene Maß, und das ist rund 146 × 19. Beides stimmt. Der Wert gilt, er wird nur nicht benutzt, weil ein Inline-Element ihn nicht verwenden kann. Beim Block darüber sind die beiden Angaben deckungsgleich: width: 364px und gemessene 364 × 19.
Merk dir den Unterschied, er erklärt später eine ganze Reihe von Fällen: Was im Reiter „Werte” steht, ist der Wert, mit dem der Browser rechnet. Was oben als Maß steht, ist das Ergebnis. Wo die beiden auseinandergehen, hat eine Regel des Layouts dazwischengefunkt.
Die Lösung dafür kennst du aus Lektion 4.5: display: inline-block oder gleich block. Dort steht auch die Ausnahme, die man hier leicht übersieht: Ein img ist ebenfalls inline und nimmt Breite, Höhe und senkrechte Außenabstände trotzdem an, weil sein Inhalt vom Browser kommt und eigene Maße mitbringt.
Textumfluss mit float
<p class="ohne">
<img src="/lernen/media/demo-600.jpg" alt="" width="140" height="79">
Ohne float steht das Bild in der Zeile und schiebt sie auseinander. Der Text darunter beginnt erst nach dem Bild.
</p>
<p class="mit">
<img src="/lernen/media/demo-600.jpg" alt="" width="140" height="79">
Mit float wandert das Bild an den Rand, und die Zeilen legen sich darum herum. Genau dafür wurde float einmal erfunden.
</p> p {
max-width: 420px;
margin-bottom: 24px;
font-family: system-ui, sans-serif;
line-height: 1.5;
background-color: #f4f4f5;
}
.mit img {
float: left;
margin-right: 16px;
} float nimmt ein Element aus der normalen Reihenfolge und schiebt es an den linken oder rechten Rand seines Containers. Der Text daneben legt sich darum.
Bis etwa 2015 wurden mit float ganze Seitenlayouts gebaut, weil es nichts Besseres gab. Zwei Spalten, drei Spalten, Navigationsleisten: alles schwebte. Das war nie dafür gedacht und entsprechend mühsam.
Heute gibt es Flexbox und Grid, und für float bleibt genau der eine Fall übrig, für den es erfunden wurde: ein Bild, um das Text herumfließen soll. Für alles andere ist es die falsche Wahl.
clear ist der Gegenspieler: clear: left sorgt dafür, dass ein Element erst unterhalb aller linken Floats beginnt. Man braucht es selten, seit es die Lösung im nächsten Abschnitt gibt.
Der Container, der zusammenklappt
<div class="kasten ohne">
<img src="/lernen/media/demo-600.jpg" alt="" width="140" height="79">
<p>Kurzer Text neben einem hohen Bild.</p>
</div>
<div class="kasten mit">
<img src="/lernen/media/demo-600.jpg" alt="" width="140" height="79">
<p>Derselbe Inhalt, der Kasten reicht bis unter das Bild.</p>
</div> .kasten {
margin-bottom: 32px;
font-family: system-ui, sans-serif;
background-color: #fef9c3;
border: 2px solid #a16207;
}
.kasten img {
float: left;
margin-right: 16px;
}
.kasten p {
margin: 0;
}
/* Ein schwebendes Kind zählt für die Höhe des Elternteils
nicht mit. Der gelbe Kasten endet deshalb oben. */
.ohne {
display: block;
}
/* flow-root macht aus dem Kasten einen eigenen kleinen
Fluss, und darin zählt das Bild wieder mit. */
.mit {
display: flow-root;
} Und hier kommt die Eigenheit, die float seinen Ruf eingebracht hat: ein schwebendes Kind zählt für die Höhe seines Elternteils nicht mit.
Im Beispiel steht ein hohes Bild in einem Kasten mit wenig Text. Der obere Kasten endet unter dem Text, das Bild ragt aus ihm heraus, und sein Rahmen läuft mitten durch. Das sieht nach einem Fehler aus und ist genau das, was im Standard steht.
Jahrelang half man sich mit einem leeren Element und clear: both darunter oder mit dem berühmten Clearfix aus einem ::after-Pseudoelement. Beides braucht man nicht mehr.
display: flow-root macht aus dem Element einen eigenen kleinen Fluss, und darin zählen die Floats wieder mit. Eine Zeile, kein zusätzliches Markup, kein Pseudoelement.
Nebenbei löst dasselbe Schlüsselwort noch ein zweites Problem: In einem flow-root fällt auch kein Außenabstand mehr aus dem Container heraus. Das ist das Margin Collapsing aus Lektion 4.4, und flow-root ist die sauberste der Gegenmaßnahmen, die dort aufgezählt sind.
Warum diese Lektion vor position steht
Die nächsten sechs Lektionen handeln davon, Elemente aus dem Fluss zu nehmen oder in ihm zu verschieben. Jede dieser Möglichkeiten kostet etwas: ein Element, das aus dem Fluss ist, macht keinen Platz mehr für sich frei, und alles, was darunter liegt, weiß nichts von ihm.
Deshalb der Satz, der über dem ganzen Abschnitt steht: positioniere nur, was sich anders nicht bauen lässt. Ein Badge in einer Kartenecke, ein Overlay über einem Bild, eine klebende Kopfzeile: dafür gibt es keinen anderen Weg. Zwei Spalten nebeneinander dagegen sind eine Aufgabe für Flexbox oder Grid, und ein Abstand zwischen zwei Absätzen ist eine Aufgabe für margin.
Zum Mitnehmen
Die häufigste richtige Antwort auf ein Layout-Problem lautet: gar nicht positionieren. Jede Positionierung nimmt ein Element aus dem Fluss oder verschiebt es darin, und beides muss man sich verdienen.
Jetzt du
Basis Konto, kostenlosZu dieser Lektion gehört eine Aufgabe. Du schreibst den Code selbst, und nach jedem Lauf sagt dir eine Prüfliste, was schon stimmt.
Dafür brauchst du das Basis Konto. Es kostet nichts, und ein Passwort gibt es auch nicht.
Was in dieser Lektion steckt
-
Artikel mit 3 Beispielen zum Ausprobieren
Steht hier, ohne Konto lesbar.
-
Aufgabe im Editor, direkt im Browser geprüft
Öffnet sich mit dem Basis Konto.