430 Stimmen

Warum funktioniert dieser CSS-Stil margin-top nicht?

Ich versuche, die margin Werte auf einer div in einem anderen div . Alles funktioniert gut, bis auf den oberen Wert, der anscheinend ignoriert wird. Aber warum?

Was ich erwartet habe:
What I expected with margin:50px 50px 50px 50px;

Was ich bekomme:
What I get with margin:50px 50px 50px 50px;

Code:

#outer {
  width: 500px;
  height: 200px;
  background: #FFCCCC;
  margin: 50px auto 0 auto;
  display: block;
}

#inner {
  background: #FFCC33;
  margin: 50px 50px 50px 50px;
  padding: 10px;
  display: block;
}

<div id="outer">
  <div id="inner">
    Hello world!
  </div>
</div>

W3Schulen keine Erklärung dafür haben, warum margin verhält sich auf diese Weise.

550voto

BoltClock Punkte 660640

Sie sehen tatsächlich den oberen Rand der #inner Element zusammenbrechen in den oberen Rand des #outer Element, so dass nur das #outer Rand intakt (auch wenn er auf Ihren Bildern nicht zu sehen ist). Die Oberkanten der beiden Kästen liegen bündig aneinander, da ihre Ränder gleich sind.

Hier sind die relevanten Punkte aus der W3C-Spezifikation:

8.3.1 Zusammenbrechende Margen

In CSS können die aneinander grenzenden Ränder von zwei oder mehr Feldern (die Geschwister sein können oder auch nicht) zu einem einzigen Rand zusammengefasst werden. Ränder, die auf diese Weise kombiniert werden, werden als zusammenbrechen und die daraus resultierende kombinierte Marge wird als kollabierter Rand .

Angrenzende vertikale Ränder brechen zusammen [...]

Zwei Ränder sind Angrenzend an wenn und nur wenn:

  • beide zu Inflow-Block-Level-Boxen gehören, die am gleichen Blockformatierungskontext teilnehmen
  • keine Linienboxen, kein Abstand, keine Polsterung und kein Rand trennen sie
  • gehören beide zu vertikal benachbarten Kastenkanten, d. h. sie bilden eines der folgenden Paare:
    • oberer Rand eines Rahmens und oberer Rand des ersten untergeordneten Rahmens im Fluss

Sie können eine der folgenden Maßnahmen ergreifen, um zu verhindern, dass der Rand kollabiert:

Der Grund, warum die oben genannten Optionen verhindern, dass die Marge zusammenbricht, ist folgender:

  • Die Ränder zwischen einem schwebenden Rahmen und einem anderen Rahmen werden nicht reduziert (auch nicht zwischen einem schwebenden Rahmen und seinen untergeordneten Rahmen).
  • Die Ränder von Elementen, die neue Blockformatierungskontexte erstellen (wie z. B. Floats und Elemente mit einem anderen Überlauf als "sichtbar"), werden nicht zusammen mit ihren Inflow-Kindern reduziert.
  • Die Ränder von Inline-Block-Boxen werden nicht kollabiert (auch nicht mit ihren Inflow-Kindern).

Der linke und der rechte Rand verhalten sich so, wie Sie es erwarten, denn:

Die waagerechten Ränder klappen nie zusammen.

133voto

enderskill Punkte 6978

Versuchen Sie es mit display: inline-block; auf der inneren div . Etwa so:

#outer {
    width:500px; 
    height:200px; 
    background:#FFCCCC;
    margin:50px auto 0 auto;
    display:block;
}
#inner {
    background:#FFCC33;
    margin:50px 50px 50px 50px;
    padding:10px;
    display:inline-block;
}

33voto

Qiang Punkte 1398

Was @BoltClock erwähnt hat, ist ziemlich solide. Und hier möchte ich nur einige weitere Lösungen für dieses Problem hinzufügen. Schau mal hier w3c_collapsing margin . Die grünen Teile sind der potenzielle Gedanke, wie dieses Problem gelöst werden kann.

Lösung 1

Die Ränder zwischen einem schwebenden Rahmen und einem anderen Rahmen werden nicht reduziert (auch nicht zwischen einem schwebenden Rahmen und seinen untergeordneten Rahmen).

das heißt, ich kann hinzufügen float:left entweder zu #outer o #inner Demo1 .

beachten Sie auch, dass float würde die auto am Rande.

Lösung 2

Die Ränder von Elementen, die neue Blockformatierungskontexte erstellen (wie z. B. Floats und Elemente mit einem anderen Überlauf als "sichtbar"), werden nicht mit ihren Inflow-Kindern reduziert.

andere als visible setzen wir overflow: hidden in #outer . Und dieser Weg scheint ziemlich einfach und anständig zu sein. Ich mag es.

#outer{
    width: 500px;
    height: 200px;
    background: #FFCCCC;
    margin: 50px auto;
    overflow: hidden;
}
#inner {
    background: #FFCC33;
    height: 50px;
    margin: 50px;
}

Lösung 3

Die Ränder von absolut positionierten Boxen werden nicht kollabiert (auch nicht mit ihren In-Flow-Kindern).

#outer{
    width: 500px;
    height: 200px;
    background: #FFCCCC;
    margin: 50px auto;
    position: absolute; 
}
#inner{
    background: #FFCC33;
    height: 50px;
    margin: 50px;
}

o

#outer{
    width: 500px;
    height: 200px;
    background: #FFCCCC;
    margin: 50px auto;
    position: relative; 
}
#inner {
    background: #FFCC33;
    height: 50px;
    margin: 50px;
    position: absolute;
}

werden diese beiden Methoden den normalen Fluss der div

Lösung 4

Die Ränder von Inline-Block-Boxen werden nicht kollabiert (auch nicht mit ihren Inflow-Kindern).

ist dasselbe wie @enderskill

Lösung 5

Der untere Rand eines fließenden Block-Level-Elements kollabiert immer mit dem oberen Rand seines nächsten fließenden Block-Level-Geschwisters, es sei denn, dieses Geschwister hat einen Abstand.

Dies hat nicht viel mit der Frage zu tun, da es sich um den kollabierenden Rand zwischen den Geschwistern handelt. es bedeutet im Allgemeinen, dass, wenn eine Top-Box margin-bottom: 30px und eine Geschwister-Box hat margin-top: 10px . Die Gesamtspanne zwischen ihnen beträgt 30px anstelle von 40px .

Lösung 6

Der obere Rand eines fließenden Blockelements kollabiert mit dem oberen Rand seines ersten fließenden Blockebenen-Kindes, wenn das Element keinen oberen Rand und keine obere Polsterung hat und das Kind keinen Abstand hat.

Das ist sehr interessant, und ich kann nur eine obere Grenzlinie hinzufügen

#outer{
    width: 500px;
    height: 200px;
    background: #FFCCCC;
    margin: 50px auto;
    border-top: 1px solid red;

}
#inner {
    background: #FFCC33;
    height: 50px;
    margin: 50px;

}

Und auch <div> ist standardmäßig Block-Level, so dass Sie nicht haben, um es absichtlich zu deklarieren. Es tut mir leid, dass ich nicht mehr als 2 Links und Bilder posten kann, da ich ein Anfänger bin. Wenigstens wissen Sie, woher das Problem kommt, wenn Sie das nächste Mal etwas Ähnliches sehen.

23voto

Brandon Punkte 67029

Ich weiß nicht, warum das, was Sie haben, nicht funktioniert, aber Sie können Folgendes hinzufügen overflow: auto; zum äußeren div .

20voto

harriyott Punkte 10317

Ich weiß nicht genau, warum, aber wenn ich das innere CSS auf

display: inline-block;

scheint zu funktionieren.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X