Wie funktioniert der CSS-Blockformatierungskontext?

80

Wie funktioniert der CSS-Blockformatierungskontext ?

Gemäß den CSS2.1-Spezifikationen sind die Felder in einem Blockformatierungskontext vertikal angeordnet, beginnend oben. Dies geschieht auch dann, wenn schwebende Elemente im Weg sind, es sei denn, das Blockfeld hat einen neuen Blockformatierungskontext eingerichtet. Wie wir wissen, wird beim Rendern von Blockboxen in einem Blockformatierungskontext das schwebende Element weggelassen. Warum funktioniert das Einrichten eines neuen Blockformatierungskontexts?

Wie sind Boxen (Blockboxen und Inline-Boxen) im normalen Ablauf angeordnet?

Ich habe irgendwo gelesen, dass Blockelemente Blockboxen erzeugen, aber schwebende Elemente werden ignoriert, wenn ein Benutzeragent Box zeichnet, und berücksichtigen sie, wenn sie Inhalte ausfüllen. Während schwebende Elemente die Grenzen der Boxen anderer Elemente überlappen, erstellt die Lösung einen neuen Blockformatierungskontext für die überlappenden Elemente mithilfe von overflow:hidden.

"Neuer Blockformatierungskontext ist immer noch Blockformatierung". Wenn Sie also eine Box zeichnen, wird das schwebende Element so behandelt, als würde es nicht beendet. Ist das richtig oder habe ich den "neuen Blockformatierungskontext" falsch verstanden?

Update: weitere Fragen

Mit den Worten "Dieses Verhalten ist nützlich für Layouts im Spaltenstil. Die Hauptverwendung besteht jedoch darin, Floats zu stoppen, beispielsweise in einem Div" Hauptinhalt ", und tatsächlich schwebende Seitenspalten zu löschen, dh Floats, die früher im Quellcode erscheinen."

Ich verstehe die Bedeutung nicht, ich werde ein Beispiel geben, vielleicht wirst du mich verstehen.

Ich dachte, die schwebende Box sollte an die Spitze des Containg-Blocks schweben - das Div mit Klasse content. Wenn das schwebende Feld früher im Markup angezeigt wird, wird außerdem angezeigt, was ich denke, dass es sein sollte.

Wie können wir das erklären? Können wir "Blockformatierungskontext und Inline-Formatierungskontext" verwenden, um dies zu erklären?

Eileen Tao
quelle
Könnten Sie ein Bild hinzufügen, um zu dokumentieren, was Sie nicht verstehen?
Mrk
Ich weiß, dass Sie nicht explizit nach Floats gefragt haben, aber ich denke, dieser Artikel ist wirklich gut darin, zu erklären, wie der Fluss einer Webseite funktioniert, und er kann Ihnen dabei helfen, dies zu verstehen.
Niklas Wulff

Antworten:

126

Formatierungskontexte blockieren

Gleitkommazahlen, absolut positionierte Elemente, Blockcontainer (wie Inline-Blöcke, Tabellenzellen und Tabellenbeschriftungen), die keine Blockboxen sind, und Blockboxen mit einem anderen Überlauf als "sichtbar" (außer wenn dieser Wert weitergegeben wurde) im Ansichtsfenster) neue Blockformatierungskontexte für deren Inhalt einrichten .

Mit meiner Kühnheit ist es das etablierte Bit, das wichtig ist

Dies bedeutet, dass das Element, das Sie verwenden overflow(alles andere als sichtbar) oder floatoder inline-blockusw., für das Layout seiner untergeordneten Elemente verantwortlich wird. Es sind die untergeordneten Elemente, die dann "enthalten" sind, unabhängig davon, ob es sich um schwebende oder kollabierende Ränder handelt. Sie sollten vollständig von ihrem übergeordneten Elternteil enthalten sein.

In einem Blockformatierungskontext berührt die linke Außenkante jedes Felds die linke Kante des enthaltenen Blocks (bei der Formatierung von rechts nach links berühren die rechten Kanten)

Was die obige Zeile bedeutet:

Da eine Box nur rechteckig und nicht unregelmäßig geformt sein kann, bedeutet dies, dass ein neuer Blockformatierungskontext zwischen zwei Floats (oder sogar neben einem) nicht um benachbarte seitliche Floats gewickelt wird. Die inneren untergeordneten Boxen können sich nur so weit erstrecken, dass sie den linken (oder rechten) Rand der Eltern in RTL berühren. Dieses Verhalten ist nützlich für Layouts im Spaltenstil. Die Hauptverwendung besteht jedoch darin, Floats zu stoppen, beispielsweise in einem Div "Hauptinhalt", und tatsächlich schwebende Seitenspalten zu löschen, dh Floats, die früher im Quellcode erscheinen.


Float Clearance

Unter normalen Umständen sollen Floats alle zuvor schwebenden Elemente löschen, die zuvor im gesamten Quellcode schwebten, nicht nur Ihre angezeigte "Spalte". Das aussagekräftige Zitat aus den "Float Clearance Specs" lautet:

Diese Eigenschaft gibt an, welche Seiten der Box (en) eines Elements möglicherweise nicht an eine frühere schwebende Box angrenzen. Die Eigenschaft 'clear' berücksichtigt keine Floats innerhalb des Elements selbst oder in anderen Blockformatierungskontexten

Angenommen, Sie haben ein dreispaltiges Layout, in dem die linke und die rechte Spalte nach links bzw. rechts verschoben werden. Die Seitenspalten befinden sich jetzt in neuen Blockformatierungskontexten, da sie verschoben werden (denken Sie daran, dass float auch eine der Eigenschaften ist, die einen neuen BFC erstellen ), so dass Sie Listenelemente glücklich in ihnen schweben können und sie nur Gleitkommazahlen löschen, die sich bereits in den Seitenspalten befinden, für die sie sich zuvor im Quellcode nicht mehr interessieren


Um den Hauptinhalt zu einem neuen Blockformatierungskontext zu machen oder nicht?

Jetzt, in dieser mittleren Säule, können Sie sie einfach von beiden Seiten aus einrahmen, so dass sie sauber zwischen den beiden seitlich schwebenden Säulen zu sitzen scheint und die verbleibende Breite annimmt. Dies ist ein üblicher Weg, um die gewünschte Breite zu erhalten, wenn die mittlere Säule "flüssig" ist - was der Fall ist Seien Sie in Ordnung, bis Sie Floats / Clearance in Ihrem Content-Div verwenden müssen (ein häufiges Ereignis für Benutzer von "Clearfix" -Hacks oder -Vorlagen, einschließlich dieser).

Nehmen Sie diesen sehr einfachen Code:

Es erzeugt Folgendes:

Geben Sie hier die Bildbeschreibung ein

Im Allgemeinen ist dies in Ordnung, insbesondere wenn Sie keine Hintergrundfarben oder internen (im Hauptinhalt) Floats haben. Beachten Sie, dass die Floats in Ordnung sind (noch nicht gelöscht). Sie tun wahrscheinlich das, was Sie außer ihnen tun, aber sie sind die H3Besten Der Rand und der puntere Rand des Inhalts sind im Inhaltsbereich (hellgrauer Hintergrund) nicht wirklich enthalten.

Fügen Sie also zu demselben einfachen Rand-Szenario des obigen Codes Folgendes hinzu:

.clear-r {clear: right;}

zum CSS und ändern Sie das zweite schwebende HTML-Feld in:

<div class="floated clear-r"> this a floated cleared box</div>

Diesmal bekommst du folgendes:

Geben Sie hier die Bildbeschreibung ein

Der zweite Schwimmer räumt die rechte Seite, aber die gesamte Höhe der rechten Spalte. Die rechte Spalte wird früher im Quellcode angezeigt, sodass sie wie angegeben gelöscht wird! Wahrscheinlich nicht die gewünschte Wirkung aber auch die Kenntnis h3und die pMargen sind immer noch brechen zusammen (nicht enthalten).


Erstellen Sie einen Blockformatierungskontext für die Kinder!

und schließlich die Hauptinhaltsspalte dazu bringen, die Verantwortung für ihren Inhalt zu übernehmen - ein Blockformatierungskontext zu werden : Entfernen Sie margin: 0 200px;CSS und ADD aus dem Hauptinhalt, overflow: hidden;und Sie erhalten Folgendes:

Geben Sie hier die Bildbeschreibung ein

Dies ist wahrscheinlich viel ähnlicher als das, was Sie erwarten würden. Beachten Sie, dass die Floats jetzt enthalten sind, die rechte Seitenspalte ordnungsgemäß ignoriert wird und auch die h3und p-Ränder enthalten sind, anstatt reduziert zu werden.

Mit der umfangreichen Verwendung von Resets in diesen Tagen sind die Ränder weniger auffällig (und der IE macht sie immer noch nicht ganz richtig). Was jedoch gerade mit dem "Hauptinhalt" des Zentrums passiert ist, ist, dass es zu einem Blockformatierungskontext wurde und jetzt für dessen verantwortlich ist eigene untergeordnete Elemente (Nachkommen). Es ist eigentlich sehr ähnlich wie Microsofts frühen Tagen Vorstellung von hasLayout es die gleichen Eigenschaften verwendet display: inline-block, floatund overflowalles andere als sichtbar, und natürlich Tabellenzellen immer Layout haben .. es ist jedoch ohne die Fehler;)

Hoffe das hilft ein bisschen, Fragen können Sie gerne stellen!


Update: Weitere Informationen in Frage:

Wenn Sie sagen "aber schwebende Elemente werden ignoriert, wenn der Benutzeragent ein Feld zeichnet, und berücksichtigen sie, wenn sie Inhalte ausfüllen."

Ja, Floats überlagern normalerweise ihre Containerboxen. Ist das das, was Sie über Elterngrenzen meinen? Wenn ein Blockelement gezeichnet wird und ein Float enthält, wird das übergeordnete Blockelement selbst als Rechteck unter dem Float gezeichnet, und es sind die "anonymen Inline-Felder" oder einfach "Linienfelder" der anderen untergeordneten Elemente, die gekürzt werden, um Platz zu schaffen der Schwimmer

Nehmen Sie diesen Code:

Welches produziert dies:

wie schwimmer funktionieren

Sie sehen , dass das übergeordnete Element enthält nicht tatsächlich den Schwimmer, wie in es nicht ganz umbrochen .. der Schwimmer ist einfach schwimmend oben auf den Inhalt - wenn Sie den div Hinzufügen von Inhalten zu halten wäre , würde es schließlich wickeln unter dem Float, da sich die (anonymen) "Line Boxes" des pElements nicht mehr verkürzen müssten.

Ich habe das Absatzelement eingefärbt, damit Sie sehen können, dass es auch tatsächlich unter dem Float steht. Auf dem dunkelgrauen Hintergrund beginnt der Absatz, auf dem weißen Text beginnt das "anonyme Zeilenfeld" - nur sie "schaffen Platz" "für den Float, sofern Sie nichts anderes angeben (dh Sie ändern den Kontext)

Wenn Sie sich wieder auf das obige Bild beziehen und die linke Seite des pElements umrandeten, wird der Textumbruch unter dem unteren Rand des Gleitkommas gestoppt, da die "Linienfelder" (der weiße Text) nur den linken Rand von berühren Sie werden den farbigen Hintergrund von prechts vom Float entfernen, aber Sie haben das Verhalten des pFormatierungskontexts nicht geändert . Wie die mittlere Spalte im ersten Bild oben;)

clairesuzy
quelle
clairesuzy, vielen dank! Es hilft mir wirklich sehr. Aber ich habe noch einige Fragen. Ich habe es zu den ursprünglichen Fragen hinzugefügt. Ich hoffe, Sie können mir helfen.
Eileen Tao
1
@eileen Es gibt zwei Dinge - ich denke, Ihre zusätzliche Frage wird durch das erste Beispiel erklärt. Die lila schwebenden Kästchen erscheinen nach dem Inhalt, weil sie sich dort in der Quelle befinden. Ein Float schwebt nicht nach oben Inhalt (wie in seinem oberen Rand kann nicht höher sein als es sein sollte) - die linke und rechte Spalte sind ebenfalls schwebende Kästchen, die sich früher in der Quelle befinden und ohne dass die mittlere Spalte zu einem neuen BFC wird, wenn Sie versuchen, die violetten Gleitkommazahlen zu löschen wird auch die früheren in der Quellseite schwebenden Spalten löschen .. hilft das?
clairesuzy
1
@eileen dieser Link beschreibt Elemente auf Blockebene und Elemente auf Inline-Ebene, nur die Grundlagen nicht so sehr in einem Formatierungskontext. Blockelemente haben immer eine Breite von 100% und sitzen (standardmäßig) übereinander - Inline-Elemente sitzen nebeneinander, wie Links, Spannweiten usw. Sie haben nicht einmal eine Breite oder Höhe, sodass sie keine Option haben. Ein schwebendes Element wird automatisch zu einem Blockebenenelement. Wenn Sie also eine Inline-Ebene schweben <span>lassen, wird es zu einer Blockebene <div>.
clairesuzy
1
Der Grund dafür, dass der pHintergrund des Floats unter den Float fällt, ist, dass schwebende Elemente aus dem Flow entfernt werden, da die benachbarten Elemente wirklich nicht wissen, dass sie vorhanden sind, und dass sie zu demselben Formatierungskontext gehören, nach dem sie paussehen Es ist ein übergeordneter Container für seine Abmessungen. (Aus diesem Grund können Sie kein 100% breites Objekt neben einen Float stellen, da 100% 100% des Containers ausmachen. Nur die anonymen Boxen stellen schließlich fest, dass der Float vorhanden ist. )
clairesuzy
1
@clairesuzy - Das Bild, das du gepostet hast, ist raus. Könntest du es bitte erneut posten?
Bfavaretto