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?
Antworten:
Formatierungskontexte blockieren
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) oderfloat
oderinline-block
usw., 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.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:
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:
Code-Snippet anzeigen
#left-col { border: 1px solid #000; width: 180px; float: left; } #right-col { border: 1px solid #000; width: 180px; float: right; height: 200px; } #content { background: #eee; margin: 0 200px; } .floated { float: right; width: 180px; height: 100px; background: #dad; }
<div id="left-col">left column</div> <div id="right-col">right column</div> <div id="content"> <h3>Main Content</h3> <p>Lorem ipsum etc..</p> <div class="floated">this a floated box</div> <div class="floated">this a floated box</div> </div>
Es erzeugt Folgendes:
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
H3
Besten Der Rand und derp
untere 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>
Code-Snippet anzeigen
#left-col { border: 1px solid #000; width: 180px; float: left; } #right-col { border: 1px solid #000; width: 180px; float: right; height: 200px; } #content { background: #eee; margin: 0 200px; } .floated { float: right; width: 180px; height: 100px; background: #dad; } .clear-r { clear: right; }
<div id="left-col">left column</div> <div id="right-col">right column</div> <div id="content"> <h3>Main Content</h3> <p>Lorem ipsum etc..</p> <div class="floated">this a floated box</div> <div class="floated clear-r">this a floated cleared box</div> </div>
Diesmal bekommst du folgendes:
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
h3
und diep
Margen 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:Code-Snippet anzeigen
#left-col { border: 1px solid #000; width: 180px; float: left; } #right-col { border: 1px solid #000; width: 180px; float: right; height: 200px; } #content { background: #eee; overflow: hidden; } .floated { float: right; width: 180px; height: 100px; background: #dad; } .clear-r { clear: right; }
<div id="left-col">left column</div> <div id="right-col">right column</div> <div id="content"> <h3>Main Content</h3> <p>Lorem ipsum etc..</p> <div class="floated">this a floated box</div> <div class="floated clear-r">this a floated cleared box</div> </div>
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
h3
undp
-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
,float
undoverflow
alles 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:
Code-Snippet anzeigen
#content { background: #eee; color #000; border: 3px solid #444; } .float { background: rgba(0, 0, 255, 0.5); border: 1px solid #00f; width: 150px; height: 150px; float: left; margin: 10px; } p { background: #444; color: #fff; }
<div id="content"> <div class="float">floated box</div> <h3>This is a content box</h3> <p>it contains a left floated box, you can see the actual content div does go under the float, but that it is the <h3> and <p> <b>line boxes</b> that are shortened to make room for the float, this is normal behaviour</p> </div>
Welches produziert dies:
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
p
Elements 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
p
Elements 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 vonp
rechts vom Float entfernen, aber Sie haben das Verhalten desp
Formatierungskontexts nicht geändert . Wie die mittlere Spalte im ersten Bild oben;)quelle
<span>
lassen, wird es zu einer Blockebene<div>
.p
Hintergrund 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 siep
aussehen 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. )