Jak działają ujemne marginesy w CSS i dlaczego (margin-top: -5!= margin-bottom: 5)?

Powszechną sztuczką dla pionowych elementów pozycjonujących jest użycie następującego CSS:

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

Gdy widzisz w widoku metric tak jak w Chrome to widzisz:

Tutaj wpisz opis obrazka

Jednak nie ma żadnego marginesu wizualnego, gdy najedziesz na element, tzn. margines jest "poza" granicą i można go zwizualizować. Ale ujemne marże się nie pojawiają. Jak wyglądają i czym się różnią?

Dlaczego jest margin-top:-8px nie to samo co margin-bottom:8px?

Więc jak działają negatywne marginesy i jaka jest intuicja za nimi. W jaki sposób "podbijają" (w przypadku margin-top < 0) przedmiot?

 117
Author: PhD, 2012-07-15

8 answers

Marginesy ujemne są ważne w css, a zrozumienie ich (zgodnego) zachowania opiera się głównie na modelu box i załamywaniu marginesów. Chociaż niektóre scenariusze są bardziej złożone, można uniknąć wielu typowych błędów po przestudiowaniu specyfikacji.

na przykład, renderowanie przykładowego kodu jest kierowane przez specyfikację css, jak opisano w obliczanie wysokości i marginesów dla absolutnie umieszczonych nie zastąpionych elementów .

If I were to make a graficzna reprezentacja, ja bym pewnie poszedł z czymś takim (nie do skalowania):

ujemny górny margines

margin box stracił 8px na górze, jednak nie ma to wpływu na content & padding Box . Ponieważ twój element jest całkowicie ustawiony, przesunięcie elementu 8px w górę nie powoduje żadnych dalszych zakłóceń w układzie; ze statyczną zawartością w przepływie nie zawsze tak jest.

Bonus:

Wciąż trzeba przekonywać, że czytanie specyfikacji jest the way to go (w przeciwieństwie do artykułów takich jak ten)? Widzę, że próbujesz wyśrodkować element pionowo, więc dlaczego musisz ustawić margin-top:-8px;, a nie margin-top:-50%;? Centrowanie pionowe w CSS jest trudniejsze niż powinno być . Podczas ustawiania parzystych marginesów top lub bottom W %, wartość jest obliczana jako procent zawsze względem szerokości bloku zawierającego. Jest to raczej częsta pułapka i dziwactwo jest rzadko opisane poza w3 doco
 95
Author: o.v.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:54:48

Postaram się to wyjaśnić wizualnie:

/**
 * 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>
 89
Author: Ana,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-28 07:42:17

Margines jest odstępem Na zewnątrz elementu, podobnie jak wypełnienie jest odstępem wewnątrz elementu.

Ustawienie dolnego marginesu wskazuje jaką odległość chcesz poniżej bieżącego bloku. Ustawienie ujemnego górnego marginesu oznacza, że chcesz mieć ujemne odstępy nad blokiem. Ujemne odstępy same w sobie mogą być mylącym pojęciem, ale tylko w sposób, w jaki dodatni górny margines popycha zawartość w dół, ujemny górny margines wciąga zawartość w górę.

 36
Author: David Hedlund,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-15 20:12:09

Margin-top of-8px oznacza, że będzie ona o 8px wyższa niż gdyby miała 0 marginesów.

Margin-bottom 8px oznacza, że rzecz poniżej będzie 8px dalej w dół, jeśli ma 0 margin.

 28
Author: Rich Bradshaw,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-15 20:09:25

Dobre uwagi już tutaj, ale choć jest wiele informacji o Jak renderowanie marginesów odbywa się przez przeglądarkę, Dlaczego jeszcze nie do końca odpowiedział:

"Dlaczego margin-top:-8px nie jest tym samym co margin-bottom: 8px?"

Możemy również zapytać:

Dlaczego dodatni dolny margines nie "podskakuje" przed elementami, podczas gdy dodatni górny margines "podskakuje" po żywioły?

Widzimy więc, że istnieje różnica w renderowaniu marginesów w zależności od strony, do której są stosowane - górny (i lewy) marginesy różnią się od dolnego (i prawego).

Rzeczy stają się jaśniejsze, gdy przeglądarka ma (uproszczone) spojrzenie na stosowanie stylów: elementy są renderowane odgórnie w widoku, zaczynając od lewego górnego rogu (na razie trzymajmy się renderowania pionowego, pamiętając, że pozioma jest traktowana tak samo).

Rozważ następujący html:

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

Analogicznie do ich pozycji w kodzie, te trzy pola pojawiają się ułożone "góra-dół" w przeglądarce (zachowując prostotę, nie będziemy tutaj rozważać właściwości order modułu CSS3 'flex-box' ). tak więc, ilekroć style są stosowane do pola 3, pozycje elementów poprzedzających (dla pola 1 i 2) zostały już określone i nie powinny być już zmieniane ze względu na szybkość renderowania.

Wyobraź sobie górny margines-10px dla pola 3. zamiast przesuwać wszystkie poprzednie elementy, aby zebrać trochę miejsca, przeglądarka po prostu przesunie box 3 w górę, więc będzie renderowany na górze (lub pod spodem, w zależności od indeksu z) wszystkich poprzedzających elementów. nawet jeśli wydajność nie była problemem, przesunięcie wszystkich elementów w górę może oznaczać przesunięcie ich poza wizjer, więc obecna pozycja przewijania musiałaby zostać zmieniona, aby wszystko było widoczne ponownie.

To samo dotyczy DNA margines dla ramki 3, zarówno ujemny, jak i dodatni: zamiast wpływać na już ocenione elementy, określa się jedynie nowy "punkt wyjścia" dla przyszłych elementów. w ten sposób ustawienie dodatniego marginesu dolnego przesunie następujące po elementy w dół; ujemny przesunie je w górę.

 25
Author: schellmax,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-16 09:06:13

Ponieważ użyłeś absolutnego pozycjonowania i podałeś górny procent, tylko margin-top wpłynie na lokalizację Twojego.obiekt item. Jeśli zamiast tego ustawisz go za pomocą bottom: 50%, wtedy potrzebujesz margin-bottom-8px, aby go wyśrodkować, a margin-top nie miałby żadnego efektu.

Margines wpływa na granice elementu pod względem jego pozycjonowania, absolutnie jak w Twoim przypadku, lub względem sąsiednich elementów. Wyobraź sobie, że margines jest fundamentem twojego elementu na który siedzi. Zazwyczaj mają taki sam rozmiar, ale mogą być większe lub mniejsze na dowolnej lub wszystkich czterech krawędziach.

Twój CSS mówi przeglądarce, aby ustawiła górny element marginesu w punkcie 50% drogi w dół strony. Ponieważ jednak wszystkie elementy nie są pojedynczym pikselem, przeglądarka musi wiedzieć, która jej część ma znaleźć się 50% W Dół strony. Do wyrównania górnej części elementu używa górnego marginesu. Domyślnie jest to zgodne z górną częścią elementu, ale możesz to zmienić za pomocą CSS.

W Twoim przypadku top 50% spowoduje, że góra elementu zacznie się na środku strony. Stosując ujemny górny margines, przeglądarka używa punktu 8px do elementu od góry (tj. linii przez środek) jako miejsca do pozycji na 50%.

Jeśli zastosujesz dodatni margines na dole, rozszerzy to linię używaną przez przeglądarkę do pozycjonowania dołu z dala od samego elementu, dając lukę między nim a dowolnym elementem element sąsiadujący poniżej lub wpływający na to, gdzie jest umieszczony absolutnie, jeśli pozycjonowanie oparte na dnie.

 3
Author: Rob Trickey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-15 20:38:38

Zastanawiam się, czy odpowiedź na to pytanie jest dobra: jak działają marginesy css i dlaczego jest tak, że margin-top: -5; nie jest tym samym co margin-bottom: 5;?

Margines jest odległością od otoczenia elementu. margin-top mówi"... odległość od otoczenia, jak mierzymy od górnej ' strony 'elementu' box 'i margin-bottom jest odległością od dolnej 'strony' 'box'". Następnie margin-top: 5; dotyczy górnego "bocznego" obwodu, -5 w tym przypadku; wszystko zbliża się od górna "strona" może nakładać się na górną "stronę" elementu przez 5, a margin-bottom: 5; oznacza, że odległość między dolną "stroną" elementu a otoczeniem wynosi 5.

W Zasadzie to, ale dotknięte przez elementy float ' a i tym podobne: http://www.w3.org/TR/CSS2/box.html#margin-properties .

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

Jestem do poprawienia.

 3
Author: Maybe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-16 03:04:05

Po prostu ująć rzeczy inaczej niż wielkie odpowiedzi powyżej, ponieważ to pomogło mi uzyskać intuicyjne zrozumienie negatywnych marginesów:

ujemny margines na elemencie pozwala mu pochłonąć przestrzeń swojego macierzystego pojemnika.

Dodanie (dodatniego) marginesu na dole nie pozwala elementowi na to - tylko odpycha ten element, który znajduje się poniżej.

 0
Author: logicOnAbstractions,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2021-01-13 22:15:44