<div style="float: left;">Left</div>
<div style="float: right;">Right</div>
<div style="clear: both; margin-top: 200px;">Main Data</div>
Warum margin:top
funktioniert das für 'Hauptdaten' im obigen Code nicht?
<div style="float: left;">Left</div>
<div style="float: right;">Right</div>
<div style="clear: both; margin-top: 200px;">Main Data</div>
Warum margin:top
funktioniert das für 'Hauptdaten' im obigen Code nicht?
Antworten:
Sie könnten die beiden schwebenden Divs in ein anderes setzen , das den Satz "overflow: hidden" hat:
<div style='overflow:hidden'> <div style="float: left;">Left</div> <div style="float: right;">Right</div> </div> <div style="clear: both; margin-top: 200px;">Main Data</div>
edit - Um dieser 5-jährigen Antwort etwas hinzuzufügen: Ich denke, die Ursache für das verwirrende Verhalten ist der etwas komplizierte Prozess des Randkollapses . Ein guter Trick mit dem ursprünglichen HTML aus dem OP ist das Hinzufügen einer CSS-Regel wie folgt:
div { border: 1px solid transparent; }
Poof! Jetzt (ohne mein zusätzliches
<div>
) funktioniert es gut! Nun, bis auf das zusätzliche Pixel von den Rändern. Insbesondere denke ich, dass es eine Kombination aus der Funktionsweiseclear: both
und den Randkollapsregeln ist, die zu einem unerwarteten Layout des Codes im OP führen.erneut bearbeiten - Die vollständige (und meiner Meinung nach absolut genaue) Geschichte finden Sie in Mark Amerys ausgezeichneter Antwort . Die Details haben eine gewisse Komplexität, die diese Antwort beschönigt.
quelle
Während Pointy zeigt, wie Sie die Floats in ein Div einschließen können, können Sie alternativ ein leeres Div zwischen den Floats und dem Hauptdatenabschnitt einfügen. Zum Beispiel:
<div style="float: left;">Left</div> <div style="float: right;">Right</div> <div style="clear: both;"></div> <div style="margin-top: 200px;">Main Data</div>
Dies kann sich in Fällen als nützlich erweisen, in denen das Hinzufügen eines Div-Wrappers um HTML nicht wünschenswert ist.
quelle
Die Logik dahinter in der Spezifikation ist umwerfend und beinhaltet ein kompliziertes Zusammenspiel der Regeln für die Freigabe und das Zusammenfallen von Rändern .
Sie sind vermutlich mit dem herkömmlichen CSS vertrauen Box - Modell , in dem die Content - Box innerhalb einer enthaltenen padding - Box innerhalb eines enthaltenen Grenze Feld innerhalb einer enthaltenen Marge Box :
Für Elemente,
clear
die auf etwas anderes als eingestellt sindnone
, kann eine zusätzliche Komponente in dieses Modell eingeführt werden: Abstand .Mit anderen Worten, das Box-Modell sieht in diesen Fällen wirklich eher so aus:
Aber wann wird die Freigabe eingeführt und wie groß sollte sie sein? Beginnen wir mit der ersten dieser Fragen. Die Spezifikation sagt :
Wenden wir diese Logik auf den Code des Fragestellers an. Denken Sie daran, wir versuchen, die Position des dritten Div im folgenden Code zu erklären (Hintergründe wurden hinzugefügt, um die Visualisierung zu erleichtern):
<div style="float: left; background: red;">Left</div> <div style="float: right; background: green;">Right</div> <div style="clear: both; margin-top: 200px; background: blue;">Main Data</div>
Stellen wir uns vor, wie die Spezifikation fordert uns auf, dass
clear
zu setzen istnone
auf der dritten div stattboth
. Wie würde dann der obige Ausschnitt aussehen?<div style="float: left; background: red;">Left</div> <div style="float: right; background: green;">Right</div> <div style="clear: none; margin-top: 200px; background: blue;">Main Data</div>
Hier überlappt die dritte Division die beiden schwebenden Divs. Aber warte; Warum ist das so? Sicher, es ist zulässig, dass schwebende Elemente Elemente auf Blockebene überlappen (gemäß der Floats-Spezifikation : "Da sich kein Float im Flow befindet, fließen nicht positionierte Blockboxen, die vor und nach dem Float-Box erstellt wurden, vertikal, als ob der Float nicht vorhanden wäre . " ), aber unser dritter Div hat jede Menge
margin-top
drauf und kommt nach den beiden schwebenden Divs; sollten die beiden schwebenden Divs nicht oben am Körper erscheinen und die dritte Div 200px tiefer, weit darunter?Der Grund, warum dies nicht auftritt, ist, dass der Rand des dritten Divs in den Rand des übergeordneten Divs (in diesem Fall des Körpers) fällt. Das gleiche Verhalten tritt jedoch auf, wenn Sie alle drei Divs in ein übergeordnetes Div einschließen. Die Collapsing Margin-Spezifikation (unten zitiert, wobei einige irrelevante Details weggelassen wurden) sagt uns, dass:
Die dritte Div in unserem Beispiel ist sicherlich nicht das erste Kind des Körpers , aber es ist das erste Kind im Fluss . Beachten Sie, dass gemäß https://www.w3.org/TR/CSS22/visuren.html#positioning-scheme :
Da der erste und der zweite Div in unserem Beispiel schwebend sind, fließt nur der dritte Div. Somit grenzt sein oberer Rand an den oberen Rand seines Elternteils an, und die Ränder kollabieren - was den gesamten Körper einschließlich der beiden schwebenden Elemente nach unten drückt . Somit überlappt die dritte Division ihre Geschwister, obwohl sie eine große hat
margin-top
. Folglich erfüllen wir - in diesem hypothetischen Fall, in dem das dritte Elementclear
eingestellt istnone
- die Bedingung, dass:So:
Wie viel Freiraum? Die Spezifikation bietet Browsern zwei Optionen mit einigen Erläuterungen:
Bevor wir mit der Anwendung dieser Regeln beginnen können, stoßen wir sofort auf eine Komplikation. Erinnern Sie sich an den zusammenbrechenden Spielraum, den wir im hypothetischen Fall berücksichtigen mussten, wo
clear
warnone
? Nun, in diesem nicht hypothetischen Fall, in dem wir die zu verwendende Freigabe berechnen, existiert sie nicht , weil die Existenz der Freigabe sie hemmt. Erinnern Sie sich an die zuvor zitierten Regeln für kollabierende Ränder aus 8.3.1 , die vorschreiben, dass Ränder nur dann angrenzen, wenn:(Betonung hinzugefügt). Somit grenzen der obere Rand des dritten Div und der obere Rand seines Elternteils nicht mehr aneinander. Wir können dieses Szenario vor der Freigabe in unserem Beispiel-Snippet simulieren
clear: none
, indem wirpadding-top: 1px
den Body beibehalten, aber hinzufügen , wodurch auch der Randkollaps gemäß der oben angegebenen Regel deaktiviert wird.body { padding-top: 1px; }
<div style="float: left; background: red;">Left</div> <div style="float: right; background: green;">Right</div> <div style="clear: none; margin-top: 200px; background: blue;">Main Data</div>
Jetzt, anders als beim Zusammenbruch der Ränder, liegt unsere dritte Division bequem unter ihren beiden schwebenden Geschwistern. Aber wir haben bereits beschlossen, auf der Grundlage eines hypothetischen Szenario , in dem die Margen haben Zusammenbruch, muss dieser Zwischenraum hinzugefügt werden; Alles was bleibt ist, die Höhe der Freigabe zu wählen , um:
Wir haben also keine andere Wahl, als einen negativen Abstand zum dritten Div anzuwenden , um dessen obere Randkante nach oben zu ziehen und die untere Außenkante (auch als Randkante bezeichnet ) der darüber schwebenden Elemente zu berühren . Wenn die schwebenden Elemente jeweils 10 Pixel hoch sind und der dritte Teil einen oberen Rand von 200 Pixel hat, wird ein Abstand von -190 Pixel angewendet. Das bringt uns schließlich zum Endergebnis, das der Fragesteller gesehen hat:
<div style="float: left; background: red;">Left</div> <div style="float: right; background: green;">Right</div> <div style="clear: both; margin-top: 200px; background: blue;">Main Data</div>
(Beachten Sie, dass Sie, wenn Sie das dritte Div im obigen Snippet mit den Entwicklertools Ihres Browsers untersuchen, immer noch die 200 Pixel des oberen Randes über dem Div sehen können, die weit über den Rest des Inhalts hinausgehen - es ist nur das Die gesamte Randbox wurde durch den großen negativen Abstand nach oben gezogen.)
Einfach!
quelle
overflow: auto
oderoverflow: hidden
für den übergeordneten Container sollte der Trick gemäß dem großen Hinweis in der Spezifikation unter w3.org/TR/CSS22/box.html#collapsing-margins und auch gemäß den gängigen Antworten ausgeführt werden wie stackoverflow.com/a/6204990/1709587 (obwohl es aus irgendeinem Grund nicht funktioniert, wenn der Container dasbody
Element ist). Ich bin mir nicht ganz sicher, warum dies funktioniert, da es von der Definition eines "Blockformatierungskontexts" abhängt (den ich nicht untersucht habe und derzeit nicht verstehe).Pointy und Randall Cook haben ausgezeichnete Antworten. Ich dachte, ich würde noch eine Lösung zeigen.
<div style="float: left;">Left</div> <div style="float: right;">Right</div> <div style="float: left; clear: both; margin-top: 200px;">Main Data</div>
Wenn Sie das 3. Element "float: left;" UND "klar: beides;" sollte den gewünschten Effekt haben, dem 3. Element einen Rand von 200 Pixel zu geben. Hier ist ein Link zu einem Beispiel.
Dies kann sich auch auf andere Folgeelemente auswirken, ob sie Floats sein müssen oder nicht. Es könnte jedoch auch den gewünschten Effekt haben.
quelle
Alternative Lösung:
http://jsfiddle.net/9EY4R/
Hinweis: Nachdem ich diesen Vorschlag gemacht habe, muss ich ihn sofort zurückziehen, da dies im Allgemeinen keine gute Idee ist, aber in einigen begrenzten Situationen angemessen sein kann.
<div class='order'> <div class='address'> <strong>Your order will be shipped to:</strong><br> Simon</br> 123 Main St<br> Anytown, CA, US </div> <div class='order-details'> Item 1<br> Item 2<br> Item 3<br> Item 4<br> Item 5<br> Item 6<br> Item 7<br> Item 8<br> Item 9<br> Item 10<br> </div> <div class='options'> <button>Edit</button> <button>Save</button> </div> </div>
Das Panel mit Elementen wird
order-details
mit diesem CSS aufgerufen.order-details { padding: .5em; background: lightsteelblue; float: left; margin-left: 1em; /* this margin does take effect */ margin-bottom: 1em; }
In der obigen Geige hat das gelbe Feld ein
margin-top
, aber wenn es nicht größer als das höchste schwebende Objekt ist, wird es nichts tun (das ist natürlich der springende Punkt dieser Frage).Wenn Sie
margin-top
das gelbe Feld auf 20em einstellen, wird es sichtbar, da der Rand vom oberen Rand des äußeren blauen Felds berechnet wird.quelle
Verwenden Sie stattdessen 'padding-top' in Ihrem Hauptdatenbereich. Alternativ können Sie das Hauptdaten-Div mit 'padding-top' in eins einschließen.
quelle
Versuchen Sie, einen unteren Rand für eines der schwebenden Elemente festzulegen. Alternativ können Sie die Floats in ein übergeordnetes Element einschließen und einen CSS-Hack verwenden, um es ohne zusätzliches Markup zu löschen .
quelle
Manchmal kann eine Kombination aus Positionsrelativ und Rand diese Art von Problemen lösen.
Ich verwende diese Technik für meine Alignright- und Alignleft-Klassen in WordPress.
Zum Beispiel, wenn ich einen "unteren Rand" möchte, der durch das Löschen von Elementen respektiert wird, die Sie verwenden können.
.alignright{ float: right; margin-left: 20px; margin-top: 20px; position: relative; top: -20px; }
Für Ihr Beispiel könnten Sie so etwas tun
<div style="float: left;">Left</div> <div style="float: right;">Right</div> <div style="clear: both; margin-bottom: 200px; position: relative; top: 200px;">Main Data</div>
quelle