Wie funktionieren negative Ränder in CSS und warum (Rand oben: -5! = Rand unten: 5)?

108

Ein häufiger Trick für vertikale Positionierungselemente ist die Verwendung des folgenden CSS:

.item {
    position:absolute;
    top:50%;
    margin-top:-8px; /* half of height */
    height: 16px;
}

In der Metrikansicht wie in Chrome sehen Sie Folgendes:

Geben Sie hier die Bildbeschreibung ein

Wenn Sie mit der Maus über das Element fahren, wird jedoch kein visueller Rand angezeigt, dh der Rand befindet sich außerhalb des Rahmens und kann visualisiert werden. Negative Margen werden jedoch nicht angezeigt. Wie sehen sie aus und was unterscheidet sie?

Warum ist das margin-top:-8px nicht dasselbe wie margin-bottom:8px ?

Wie funktionieren negative Margen und welche Intuition steckt dahinter? Wie "stoßen" sie (im Falle margin-top < 0) eines Gegenstands?

PhD
quelle

Antworten:

89

Negative Ränder sind in CSS gültig und das Verständnis ihres (konformen) Verhaltens basiert hauptsächlich auf dem Box-Modell und dem Zusammenfallen der Ränder . Während bestimmte Szenarien komplexer sind, können viele häufige Fehler nach dem Studium der Spezifikation vermieden werden.

Zum Beispiel wird das Rendern Ihres Beispielcodes von der CSS-Spezifikation geleitet, wie unter Berechnen von Höhen und Rändern für absolut positionierte nicht ersetzte Elemente beschrieben .

Wenn ich eine grafische Darstellung machen würde, würde ich wahrscheinlich so etwas machen (nicht maßstabsgetreu):

negativer oberer Rand

Das Randfeld,8px das oben verloren gegangen ist , hat jedoch keine Auswirkungen auf die Inhalts- und Auffüllfelder . Da Ihr Element absolut positioniert ist, führt das Verschieben des Elements um 8 Pixel nach oben nicht zu weiteren Störungen des Layouts. Bei statischen In-Flow-Inhalten ist dies nicht immer der Fall.

Bonus:

Müssen Sie immer noch davon überzeugt werden, dass das Lesen von Spezifikationen der richtige Weg ist (im Gegensatz zu Artikeln wie diesem )? Ich sehe, dass Sie versuchen, das Element vertikal zu zentrieren. Warum müssen Sie also setzen margin-top:-8px;und nicht margin-top:-50%;?

Nun, die vertikale Zentrierung in CSS ist schwieriger als es sein sollte . Wenn Sie sogar den oberen oder unteren Rand in% festlegen, wird der Wert als Prozentsatz berechnet, der immer relativ zur Breite des enthaltenen Blocks ist . Dies ist eher eine häufige Gefahr, und die Eigenart wird außerhalb von w3-Dokumenten selten beschrieben

ov
quelle
84

Ich werde versuchen, es visuell zu erklären:

/**
 * explaining margins
 */

body {
  padding: 3em 15%
}

.parent {
  width: 50%;
  width: 400px;
  height: 400px;
  position: relative;
  background: lemonchiffon;
}

.parent:before,
.parent:after {
  position: absolute;
  content: "";
}

.parent:before {
  top: 0;
  bottom: 0;
  left: 50%;
  border-left: dashed 1px #ccc;
}

.parent:after {
  left: 0;
  right: 0;
  top: 50%;
  border-top: dashed 1px #ccc;
}

.child {
  width: 200px;
  height: 200px;
  background: rgba(200, 198, 133, .5);
}

ul {
  padding: 5% 20px;
}

.set1 .child {
  margin: 0;
  position: relative;
}

.set2 .child {
  margin-left: 75px;
  position: relative;
}

.set3 .child {
  margin-left: -75px;
  position: relative;
}


/* position absolute */

.set4 .child {
  top: 50%;
  left: 50%;
  margin: 0;
  position: absolute;
}

.set5 .child {
  top: 50%;
  left: 50%;
  margin-left: 75px;
  position: absolute;
}

.set6 .child {
  top: 50%; /* level from which margin-top starts 
	- downwards, in the case of a positive margin
	- upwards, in the case of a negative margin	
	*/
  left: 50%; /* level from which margin-left starts 
	- towards right, in the case of a positive margin
	- towards left, in the case of a negative margin	
	*/
  margin: -75px;
  position: absolute;
}
<!-- content to be placed inside <body>…</body> -->
<h2><code>position: relative;</code></h2>
<h3>Set 1</h3>
<div class="parent set 1">
  <div class="child">
    <pre>
.set1 .child {
  margin: 0;
  position: relative;
}
		</pre>
  </div>
</div>

<h3>Set 2</h3>
<div class="parent set2">
  <div class="child">
    <pre>
.set2 .child {
  margin-left: 75px;
  position: relative;
}
		</pre>
  </div>
</div>

<h3>Set 3</h3>
<div class="parent set3">
  <div class="child">
    <pre>
.set3 .child {
  margin-left: -75px;
  position: relative;
}
		</pre>
  </div>
</div>

<h2><code>position: absolute;</code></h2>

<h3>Set 4</h3>
<div class="parent set4">
  <div class="child">
    <pre>
.set4 .child {
  top: 50%;
  left: 50%;
  margin: 0;
  position: absolute;
}
		</pre>
  </div>
</div>

<h3>Set 5</h3>
<div class="parent set5">
  <div class="child">
    <pre>
.set5 .child {
  top: 50%;
  left: 50%;
  margin-left: 75px;
  position: absolute;
}
		</pre>
  </div>
</div>

<h3>Set 6</h3>
<div class="parent set6">
  <div class="child">
    <pre>
.set6 .child {
  top: 50%;
  left: 50%;
  margin: -75px;
  position: absolute;
}
		</pre>
  </div>
</div>

Ana
quelle
33

Rand ist der Abstand außerhalb Ihres Elements, genauso wie Polsterung der Abstand innerhalb Ihres Elements ist.

Durch Einstellen des unteren Randes wird angegeben, welcher Abstand unter dem aktuellen Block liegen soll. Das Festlegen eines negativen oberen Randes zeigt an, dass Sie einen negativen Abstand über Ihrem Block wünschen. Negative Abstände mögen an sich ein verwirrendes Konzept sein, aber genau so, wie ein positiver oberer Rand den Inhalt nach unten drückt, zieht ein negativer oberer Rand den Inhalt nach oben.

David Hedlund
quelle
2
+1 Ich mag deine Antwort. Es kann durch Einfügen der Wörter onsetund verbessert werden offset. Es ist wahr, dass so viele Leute immer das Wort offset( negativ ) verwenden, wenn sie onset( positiv ) meinen . Diese Nachricht zerstört sich selbst, wenn Sie Ihre Antwort aktualisieren. Prost!
Arttronics
1
Was ist mit margin-bottom: -8px;? Warum ist das margin-bottom:-8pxnicht dasselbe wie margin-top:-8px?
Rick
27

Ein Rand von -8px bedeutet, dass er 8px höher ist als bei einem Rand von 0px.

Ein Rand-Bottom von 8px bedeutet, dass das darunter liegende Objekt 8px weiter unten liegt als bei einem Rand von 0px.

Rich Bradshaw
quelle
1
Ich habe nur versucht, die Dinge einfach zu halten, aber ich stimme zu, dies ist möglicherweise die schlechteste meiner Antworten!
Rich Bradshaw
2
Ich finde die Antwort ziemlich gut. Keine Verwendung hochtechnischer Antworten, die die Hälfte von uns nicht versteht.
Nummer 945
1
Was ist mit margin-bottom: -8px;? Warum ist das margin-bottom:-8pxnicht dasselbe wie margin-top:-8px?
Rick
22

Hier wurden bereits gute Punkte gemacht, aber obwohl es viele Informationen darüber gibt, wie das Rendern von Rändern durch den Browser erreicht wird, das Warum noch nicht ganz beantwortet:

"Warum ist Rand oben: -8px nicht dasselbe wie Rand unten: 8px?"

was wir auch fragen könnten ist:

Warum "stößt" ein positiver unterer Rand vorhergehende Elemente nicht an, während ein positiver oberer Rand nachfolgende Elemente "anstößt"?

Wir sehen also, dass es einen Unterschied in der Darstellung von Rändern gibt, abhängig von der Seite, auf die sie angewendet werden - die oberen (und linken) Ränder unterscheiden sich von den unteren (und rechten) Rändern.

Die Dinge werden klarer, wenn man sich (vereinfacht) ansieht, wie Stile vom Browser angewendet werden: Elemente werden im Ansichtsfenster von oben nach unten gerendert, beginnend in der oberen linken Ecke (bleiben wir zunächst beim vertikalen Rendern, wobei wir dies berücksichtigen die horizontale wird gleich behandelt).

Betrachten Sie das folgende HTML:

<div class="box1"></div>
<div class="box2"></div>
<div class="box3"></div>

Analog zu ihrer Position im Code erscheinen diese drei Felder im Browser von oben nach unten gestapelt (um die Dinge einfach zu halten, werden wir hier die orderEigenschaft des CSS3-Moduls "Flex-Box" nicht berücksichtigen ). Wenn Stile auf Feld 3 angewendet werden, wurden die Positionen der vorhergehenden Elemente (für Feld 1 und 2) bereits festgelegt und sollten aus Gründen der Rendergeschwindigkeit nicht mehr geändert werden.

Stellen Sie sich nun einen oberen Rand von -10 Pixel für Feld 3 vor. Anstatt alle vorhergehenden Elemente nach oben zu verschieben, um Platz zu schaffen, schiebt der Browser Feld 3 einfach nach oben, sodass es je nach Z-Index über (oder darunter) gerendert wird ) alle vorhergehenden Elemente. Selbst wenn die Leistung kein Problem wäre, könnte das Verschieben aller Elemente bedeuten, dass sie aus dem Ansichtsfenster verschoben werden. Daher müsste die aktuelle Bildlaufposition geändert werden, damit alles wieder sichtbar ist.

Gleiches gilt für einen unteren Rand für Feld 3, sowohl negativ als auch positiv: Anstatt bereits bewertete Elemente zu beeinflussen, wird nur ein neuer „Ausgangspunkt“ für kommende Elemente festgelegt. Wenn Sie also einen positiven unteren Rand festlegen, werden die folgenden Elemente nach unten gedrückt. ein negativer wird sie nach oben drücken.

schellmax
quelle
DIE BESTE Antwort. Dieser erklärt auch das "Warum", während die anderen Antworten nur das "Wie" erklären.
Amir Hossein Ahmadi
1
Diese Antwort half mir zu verstehen, warum besser. Vielen Dank, dass Sie @schellmax
iRamesh
3

Da Sie die absolute Positionierung verwendet und einen oberen Prozentsatz angegeben haben, wirkt sich nur der obere Rand auf die Position Ihres .item-Objekts aus. Wenn Sie es stattdessen mit dem unteren Rand: 50% positionieren würden, benötigen Sie Rand-unten -8px, um es zu zentrieren, und Rand-oben hätte keine Auswirkung.

Der Rand beeinflusst die Grenzen eines Elements in Bezug auf die Positionierung, entweder absolut wie in Ihrem Fall oder relativ zu benachbarten Elementen. Stellen Sie sich vor, der Rand ist das Fundament Ihres Elements, auf dem er sitzt. Sie haben normalerweise die gleiche Größe, können jedoch an einer oder allen vier Kanten vergrößert oder verkleinert werden.

Ihr CSS weist den Browser an, den Rand Ihres Elements am Rand 50% des Seitenabschnitts zu positionieren. Da jedoch nicht alle Elemente ein einzelnes Pixel sind, muss der Browser wissen, welcher Teil davon zu 50% auf der Seite ausgerichtet werden soll. Zum Ausrichten der Oberseite des Elements wird der obere Rand verwendet. Standardmäßig stimmt dies mit dem oberen Rand des Elements überein, Sie können es jedoch mit CSS ändern.

In Ihrem Fall würden die oberen 50% dazu führen, dass der obere Rand des Elements in der Mitte der Seite beginnt. Durch Anwenden eines negativen oberen Randes verwendet der Browser den Punkt 8px in das Element von oben (dh die Linie in der Mitte) als Position für die Position bei 50%.

Wenn Sie einen positiven Rand auf den unteren Rand anwenden, wird die Linie erweitert, die der Browser verwendet, um den unteren Rand vom Element selbst weg zu positionieren. Dadurch entsteht eine Lücke zwischen ihm und einem darunter liegenden benachbarten Element oder es wird beeinflusst, wo er absolut platziert ist, wenn die Positionierung auf basiert der Boden.

Rob Trickey
quelle
+1. Sinnvoll ... es wäre großartig, es mit visuellen Hinweisen zu ergänzen, um die Visualisierung zu vervollständigen .
PhD
3

Ich frage mich, ob diese Frage gut beantwortet wurde: Wie funktionieren CSS-Ränder und warum ist es der Rand oben: -5; ist nicht dasselbe wie Rand-unten: 5;?

Der Rand ist die Entfernung von der Umgebung des Elements. Rand oben sagt "... Abstand von der Umgebung, wenn wir von der oberen 'Seite' der 'Box' des Elements messen, und Rand-unten ist der Abstand von der unteren 'Seite' der 'Box'". Dann Rand oben: 5; befasst sich mit dem oberen Seitenumfang, in diesem Fall -5; Alles, was sich von der oberen Seite nähert, kann die obere Seite des Elements um 5 und den unteren Rand überlappen: 5; bedeutet, dass der Abstand zwischen der unteren Seite des Elements und der Umgebung 5 beträgt.

Grundsätzlich ist dies jedoch von schwebenden Elementen und dergleichen betroffen: http://www.w3.org/TR/CSS2/box.html#margin-properties .

http://coding.smashingmagazine.com/2009/07/27/the-definitive-guide-to-using-negative-margins/

Ich muss korrigiert werden.

Vielleicht
quelle