Come funzionano i margini negativi nei CSS e perché è (margin-top: -5! = Margin-bottom: 5)?


108

Un trucco comune per gli elementi di posizionamento verticale consiste nell'utilizzare il seguente CSS:

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

Se visto nella visualizzazione metrica come in Chrome, questo è ciò che vedi:

inserisci qui la descrizione dell'immagine

Tuttavia, non è rappresentato alcun margine visivo quando si passa con il mouse sull'elemento, ovvero il margine è "esterno" al bordo e può essere visualizzato. Ma i margini negativi non vengono visualizzati. Come appaiono e cosa lo rende diverso?

Perché margin-top:-8px non è lo stesso dimargin-bottom:8px ?

Quindi, come funzionano i margini negativi e qual è l'intuizione dietro di essi. Come fanno a "sollevare" (in caso di margin-top < 0) un articolo?

Risposte:


89

I margini negativi sono validi in CSS e la comprensione del loro comportamento (conforme) si basa principalmente sul modello box e sul collasso del margine. Sebbene alcuni scenari siano più complessi, è possibile evitare molti errori comuni dopo aver studiato le specifiche.

Ad esempio, il rendering del codice di esempio è guidato dalle specifiche CSS come descritto nel calcolo di altezze e margini per elementi non sostituiti posizionati in modo assoluto .

Se dovessi fare una rappresentazione grafica, probabilmente andrei con qualcosa del genere (non in scala):

margine superiore negativo

La casella del margine persa 8pxin alto, tuttavia ciò non influisce sul contenuto e sulle caselle di riempimento . Poiché il tuo elemento è posizionato in modo assoluto, spostare l'elemento di 8px verso l'alto non causa ulteriori disturbi al layout; con contenuto in-flow statico che non è sempre il caso.

Bonus:

Hai ancora bisogno di convincerti che leggere le specifiche è la strada da percorrere (al contrario di articoli come questo )? Vedo che stai cercando di centrare verticalmente l'elemento, quindi perché devi impostare margin-top:-8px;e non margin-top:-50%;?

Ebbene, il centraggio verticale nei CSS è più difficile di quanto dovrebbe essere . Quando si impostano anche i margini superiore o inferiore in%, il valore viene calcolato come percentuale sempre relativa alla larghezza del blocco contenitore . Questa è una trappola piuttosto comune e la stranezza è raramente descritta al di fuori di w3 docos


84

Proverò a spiegarlo visivamente:

/**
 * 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>


33

Il margine è la spaziatura all'esterno del tuo elemento, proprio come la spaziatura interna è la spaziatura all'interno del tuo elemento.

L'impostazione del margine inferiore indica la distanza desiderata al di sotto del blocco corrente. L'impostazione di un margine superiore negativo indica che desideri una spaziatura negativa sopra il blocco. La spaziatura negativa può di per sé essere un concetto confuso, ma proprio nel modo in cui il margine superiore positivo spinge il contenuto verso il basso, un margine superiore negativo solleva il contenuto.


2
+1 Mi piace la tua risposta. Può essere migliorato iniettando le parole onsete offset. È vero che così tante persone usano sempre la parola offset( negativo ) quando intendono onset( positivo ). Questo messaggio si autodistruggerà se aggiorni la tua risposta. Saluti!
arttronics

1
Di cosa margin-bottom: -8px;? Perché margin-bottom:-8pxnon è lo stesso di margin-top:-8px?
Rick il

27

Un margine superiore di -8px significa che sarà 8px superiore rispetto a se avesse un margine di 0.

Un margine inferiore di 8px significa che la cosa sotto sarà 8px più in basso che se avesse margine 0.


1
Stavo solo cercando di mantenere le cose semplici, ma sono d'accordo, questa è forse la peggiore delle mie risposte scritte!
Rich Bradshaw

2
Penso che risponda abbastanza bene. Nessun uso di risposte altamente tecniche che la metà di noi non ottiene.
Numero 945

1
Di cosa margin-bottom: -8px;? Perché margin-bottom:-8pxnon è lo stesso di margin-top:-8px?
Rick il

22

buoni punti già fatti qui, ma mentre ci sono molte informazioni su come il rendering dei margini viene eseguito dal browser, il motivo non è ancora stato risolto:

"Perché margin-top: -8px non è uguale a margin-bottom: 8px?"

quello che potremmo anche chiedere è:

Perché un margine inferiore positivo non "solleva" gli elementi precedenti, mentre un margine superiore positivo "abbassa" gli elementi seguenti?

quindi quello che vediamo è che c'è un file differenza nel rendering dei margini a seconda del lato a cui sono applicati : i margini superiore (e sinistro) sono diversi da quelli inferiori (e destro).

le cose diventano più chiare quando si ha uno sguardo (semplificato) a come gli stili vengono applicati dal browser: gli elementi sono renderizzati dall'alto verso il basso nella vista, iniziando dall'angolo in alto a sinistra (rimaniamo al rendering verticale per ora, tenendo presente che quello orizzontale è trattato allo stesso modo).

considera il seguente html:

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

analogamente alla loro posizione nel codice, queste tre caselle appaiono impilate 'dall'alto verso il basso' nel browser ( mantenendo le cose semplici, non considereremo qui la orderproprietà del modulo css3 'flex-box' ). così, ogni volta che gli stili vengono applicati al riquadro 3, le posizioni degli elementi precedenti (per i riquadri 1 e 2) sono già state determinate e non dovrebbero più essere modificate per motivi di velocità di rendering.

ora, immagina un margine superiore di -10px per la casella 3. invece di spostare verso l'alto tutti gli elementi precedenti per raccogliere un po 'di spazio, il browser sposterà semplicemente la casella 3 verso l'alto, quindi viene renderizzata sopra (o sotto, a seconda dello z-index ) eventuali elementi precedenti. anche se le prestazioni non fossero un problema, spostare tutti gli elementi in alto potrebbe significare spostarli fuori dalla visualizzazione, quindi la posizione di scorrimento corrente dovrebbe essere modificata per avere di nuovo tutto visibile.

lo stesso vale per un margine inferiore per il riquadro 3, sia negativo che positivo: invece di influenzare gli elementi già valutati, viene determinato solo un nuovo "punto di partenza" per gli elementi futuri. quindi impostare un margine inferiore positivo spingerà verso il basso i seguenti elementi; uno negativo li spingerà verso l'alto.


LA MIGLIORE risposta. Questa spiega anche il "perché", mentre le altre risposte spiegano solo il "come".
Amir Hossein Ahmadi,

1
Questa risposta mi ha aiutato a capire meglio il perché. Grazie @schellmax
iRamesh

3

Poiché hai utilizzato il posizionamento assoluto e specificato una percentuale superiore, solo margin-top influenzerà la posizione del tuo oggetto .item. Se invece lo posizionassi usando bottom: 50%, allora avresti bisogno di margin-bottom -8px per centrarlo e margin-top non avrebbe alcun effetto.

Il margine influenza i confini di un elemento in termini di posizionamento, sia assolutamente come nel tuo caso, sia rispetto agli elementi vicini. Immagina che il margine sia le fondamenta del tuo elemento su cui poggia. In genere hanno le stesse dimensioni, ma possono essere ingrandite o ridotte su uno o tutti i quattro bordi.

Il tuo CSS dice al browser di posizionare la parte superiore del tuo elemento al margine in un punto del 50% lungo la pagina. Tuttavia, poiché tutti gli elementi non sono un singolo pixel, il browser deve sapere quale parte di esso deve essere allineata per il 50% lungo la pagina. Per allineare la parte superiore dell'elemento, utilizza il margine superiore. Per impostazione predefinita, è in linea con la parte superiore dell'elemento, ma puoi modificarlo con CSS.

Nel tuo caso, il 50% superiore risulterebbe nella parte superiore dell'elemento che inizia al centro della pagina. Applicando un margine superiore negativo, il browser utilizza il punto 8px nell'elemento dall'alto (cioè la linea che lo attraversa al centro) come punto da posizionare al 50%.

Se applichi un margine positivo al fondo, questo estende la linea che il browser usa per posizionare il fondo lontano dall'elemento stesso, dando uno spazio tra esso e qualsiasi elemento adiacente sottostante, o influenzando dove è posizionato assolutamente se il posizionamento si basa su il fondo.


+1. Ha senso ... sarebbe fantastico aumentarlo con suggerimenti visivi in ​​modo da completare la visualizzazione .
PhD

3

Mi chiedo se a questa domanda sia stata data una buona risposta: come funzionano i margini CSS e perché è quel margin-top: -5; non è lo stesso di margin-bottom: 5 ;?

Il margine è la distanza dall'ambiente circostante l'elemento. margin-top dice "... distanza dall'ambiente circostante come misuriamo dal 'lato' superiore della 'scatola' dell'elemento e margin-bottom è la distanza dal 'lato' inferiore della 'scatola'". Quindi margin-top: 5; si occupa del perimetro "laterale" superiore, -5 in questo caso; qualsiasi cosa si avvicini dal 'lato' superiore può sovrapporsi al 'lato' superiore dell'elemento di 5 e margin-bottom: 5; significa che la distanza tra il lato inferiore dell'elemento e l'ambiente circostante è 5.

Fondamentalmente quello ma influenzato da elementi float e simili: http://www.w3.org/TR/CSS2/box.html#margin-properties .

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

Sono pronto per essere corretto.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.