Blockformatierungskontext

Aus SELFHTML-Wiki
Wechseln zu: Navigation, Suche

Wenn der Browser Elemente layouten muss, findet dies innerhalb eines Formatierungskontextes statt. Sobald ein Element Blockelemente als Kindelemente enthält, wird sein Inhalt als Blockformatierungskontext dargestellt. Finden sich nur Text oder Inline-Elemente, ist es ein Inlineformatierungskontext.

Innerhalb eines Blockformatierungskontextes werden die Elemente von oben nach unten angeordnet, und ihre linke Kante an der linken Kante ihres Containerelements ausgerichtet (bei einer Leserichtung von rechts nach links sind es die rechten Kanten). Margins, die sich überlagern, werden soweit verschmolzen, dass nur der größere Rand übrig bleibt, und float-Elemente schieben andere Elemente innerhalb des Containers beiseite.

Darstellung bei nur einem BFC ansehen …
aside {
    float: left;
    width: 10em;
}
<main>
    <aside>
        aside
    </aside>
    <section id="a">
      <p>paragraph</p>
      <p>paragraph</p>
      <p>paragraph</p>
    </section>
    <section id="b">
      Dies ist ein anderer Text
    </section>
</main>

Das ist das Grundgerüst für eine Visualisierung der Einflüsse von Blockformatierungskontexten. Schauen Sie es sich in der Vorschau an, oder durch einen Klick auf "ausprobieren", um die vollständigen Styles zu sehen. Der Body ist zur besseren Erkennbarkeit rosa gefärbt, das aside-Element ist links gefloatet und hellblau. Das main-Element ist grün hinterlegt und die Paragraphen in der #a Section sind gelb.

In dieser ersten Version gibt es zwei Blockformatierungskontexte. Der eine ist der Kontext des <body> Elements, er gilt für alles, außer für das Innere des gefloateten aside. Durch die float-Eigenschaft wird ein neuer Blockformatierungskontext begründet.

Sie sehen, wie das aside einige Textzeilen des ersten <p> Elements nach rechts schiebt. Das <p> Element an sich wird aber nicht verschoben, das erkennt man zum einen daran, dass nach dem Ende des float-Elements der Text zum linken Rand zurückkehrt, und zum anderen scheint die Hintergrundfarbe des Paragraphen um das float-aside herum noch durch.

Wir führen nun eine kleine, scheinbar nutzlose Erweiterung im CSS durch:

Ein BFC für die Paragraphen ansehen …
p {
    overflow:hidden;
}

Sie sehen, dass der erste Paragraph nun komplett eingerückt ist. Die Angabe overflow:hidden; ist eine aus einer langen Liste (siehe Weblinks), die für ein Container-Element einen neuen Blockformatierungskontext erzeugt. Das Innere eines BFC wird eigenständig layoutet, deswegen darf das float-Element nicht hineinragen und statt dessen wird der ganze Paragraph neben das float-Element gerückt.

Verschieben wir die overflow:hidden Angabe nun im DOM eine Stufe nach oben:

Ein BFC für die #a section ansehen …
section#a {
    overflow:hidden;
}
p {
}

Nun sind alle Paragraphen eingerückt. Die #a Section ist - aus dem gleichen Grund wie zuvor der Paragraph, komplett neben das float-aside gesetzt worden. Wenn Sie aber genau hinschauen, ist noch etwas anderes passiert. Bis eben war der erste Paragraph bündig mit der Oberkante der Section, und es war kein grüner Streifen zu sehen. Dort ist nun einer, und die Breite des rosa Streifens über der Section ist geringer geworden.

Der Grund dafür ist, dass ein BFC auch das Zusammenlegen von Rändern verhindert. Vorher befanden sich Section und main-Element im gleichen BFC. Der Paragraph zwar nicht mehr, aber der Margin des Elements, das den BFC trägt, ist sozusagen außerhalb des BFC und unterliegt den Randzusammenlegungen im äußeren BFC. Deswegen verschmolz der 1em Margin des p Elements mit dem 8px Margin des body (die beide aus dem Browser-Stylesheet kommen) zu einem gemeinsamen 1em Margin, was den Body insgesamt nach unten schob.

Durch den BFC auf der #a section befinden sich die Paragraphen nun in einem anderen BFC als der body und die Margins der Paragraphen bleiben innerhalb des BFC, in dem sie layoutet werden. Dadurch entsteht nun ein 1em Abstand zwischen der Oberkante von Section und Paragraph, und der body rutscht wieder auf seinen üblichen 8px Abstand.

Sie können das Verhalten der Margins mit Hilfe des Seiteninspektors in den Entwicklerwerkzeugen Ihres Browsers untersuchen. Vergleichen Sie die drei Beispielvorschauen, oder öffnen Sie sie mittels ausprobieren im Frickl und spielen Sie etwas damit herum.

Wenn Sie gut aufgepasst haben, bleibt eine Frage offen: Warum verschmilzt der Margin des float-aside nicht? Die Antwort auf diese Frage findet sich in der CSS2-Spezifikation, die hierfür immer noch aktuell ist. Sie definiert exakt die Regeln, wann Ränder verschmelzen und wann nicht, und stellt als Folgerung daraus fest, dass die Ränder von float-Elementen niemals verschmelzen.

Weblinks