CSS'de negatif kenar boşlukları nasıl çalışır ve neden (margin-top: -5! = Margin-bottom: 5)?


108

Dikey konumlandırma öğeleri için yaygın bir numara, aşağıdaki CSS'yi kullanmaktır:

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

Chrome'da olduğu gibi metrik görünümde görüldüğünde şunu görürsünüz:

görüntü açıklamasını buraya girin

Ancak, öğenin üzerine geldiğinizde tasvir edilen görsel bir kenar boşluğu yoktur, yani kenar boşluğu sınırın 'dışında' ve görselleştirilebilir. Ancak negatif marjlar görünmüyor. Nasıl görünüyorlar ve onu farklı kılan nedir?

Neden aynı margin-top:-8px değil margin-bottom:8px ?

Öyleyse, negatif marjlar nasıl çalışır ve arkasındaki sezgi nedir? margin-top < 0Bir öğeyi (olması durumunda ) nasıl 'yükseltirler' ?

Yanıtlar:


89

Negatif marjlar css'de geçerlidir ve (uyumlu) davranışlarını anlamak, temel olarak kutu modeline ve marj daralmasına dayanır . Bazı senaryolar daha karmaşık olsa da, teknik özellikleri inceledikten sonra birçok yaygın hatadan kaçınılabilir.

Örneğin, örnek kodunuzun oluşturulması, kesinlikle konumlandırılmış değiştirilmemiş elemanlar için yükseklik ve kenar boşluklarının hesaplanmasında açıklandığı gibi css spesifikasyonu tarafından yönlendirilir .

Grafiksel bir sunum yapacak olsaydım, muhtemelen şöyle bir şeyle giderdim (ölçeklendirmek için değil):

negatif üst kenar boşluğu

Marj kutusu kayıp 8pxüstüne, ancak bu etkilemez içerik ve dolgu kutuları . Öğeniz kesinlikle konumlandırıldığı için, öğeyi 8px yukarı taşımak, mizanpajı daha fazla rahatsız etmez; statik akış içi içerik ile her zaman durum böyle değildir.

Bonus:

Yine gözlük okuma olduğunu ikna gerekir (aksine gitmek için yol böyle makaleleri )? Eğer sette zorunda neden bu kadar, dikey eleman ortalamak için çalışıyoruz bkz değil ?margin-top:-8px;margin-top:-50%;

CSS'de dikey merkezleme olması gerekenden daha zor . Üst veya alt kenar boşluklarını bile % olarak ayarlarken , değer her zaman içeren bloğun genişliğine göre bir yüzde olarak hesaplanır . Bu oldukça yaygın bir tuzaktır ve tuhaflık nadiren w3 doco'ları dışında anlatılır.


84

Bunu görsel olarak açıklamaya çalışacağım:

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

Kenar boşluğu, tıpkı dolgu öğenizin içindeki aralık olduğu gibi, öğenizin dışındaki aralıktır.

Alt kenar boşluğunun ayarlanması, mevcut bloğun altında hangi mesafeyi istediğinizi belirtir. Negatif bir üst kenar boşluğu ayarlamak, bloğunuzun üzerinde negatif boşluk istediğinizi belirtir. Negatif boşluk kendi içinde kafa karıştırıcı bir kavram olabilir, ancak pozitif üst kenar boşluğunun içeriği aşağı itmesi gibi, negatif üst kenar boşluğu içeriği yukarı çeker.


2
+1 Cevabınızı beğendim. Bu kelimeleri enjekte ederek geliştirilebilir onsetve offset. Bu doğru, pek çok insan her zaman ( pozitif ) demek istediklerinde offset( negatif ) kelimesini kullanıyor . Cevabınızı güncellerseniz bu mesaj kendi kendini imha edecektir. Şerefe! onset
arttronics

1
Peki ya margin-bottom: -8px;? Neden aynı margin-bottom:-8pxdeğil margin-top:-8px?
Rick

27

Üst -8 piksel kenar boşluğu, 0 kenar boşluğuna göre 8 piksel daha yüksek olacağı anlamına gelir.

8px'lik bir kenar boşluğu, altındaki şeyin, 0 marjı varsa 8px daha aşağıda olacağı anlamına gelir.


1
Her şeyi basit tutmaya çalışıyordum, ama katılıyorum, bu muhtemelen cevaplarımın en kötüsü!
Rich Bradshaw

2
Bence cevap oldukça iyi. Yarımızın anlamadığı oldukça teknik cevaplar kullanılmaz.
Sayı945

1
Peki ya margin-bottom: -8px;? Neden aynı margin-bottom:-8pxdeğil margin-top:-8px?
Rick

22

Burada zaten iyi noktalara değinilmiştir, ancak tarayıcı tarafından kenar boşluklarının nasıl oluşturulduğu hakkında birçok bilgi olsa da , neden henüz tam olarak yanıtlanmamıştır:

"Neden margin-top: -8px, margin-bottom: 8px ile aynı değil?"

sorabileceğimiz şey şudur:

Pozitif bir alt kenar boşluğu önceki öğeleri 'yukarı kaldırırken' pozitif bir üst kenar boşluğu aşağıdaki öğeleri 'aşağıya taşır'?

bu yüzden , uygulandıkları tarafa bağlı olarak kenar boşluklarının oluşturulmasında bir fark olduğunu görüyoruz - üst (ve sol) kenar boşlukları, alt (ve sağ) kenar boşluklarından farklıdır.

Tarzların tarayıcı tarafından nasıl uygulandığına (basitleştirilmiş) bir göz atarken işler daha net hale geliyor: öğeler, sol üst köşeden başlayarak görünüm alanında yukarıdan aşağıya işleniyor (şimdilik dikey oluşturmaya bağlı kalalım, şunu unutmayın: yatay olan aynı şekilde ele alınır).

aşağıdaki html'yi düşünün:

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

Koddaki konumlarına benzer şekilde, bu üç kutu tarayıcıda 'yukarıdan aşağıya' yığılmış olarak görünür ( işleri basit tutarak, burada ordercss3 'flex-box' modülünün özelliğini dikkate almayacağız ). bu nedenle, kutu 3'e stiller uygulandığında, önceki öğenin konumları (kutu 1 ve 2 için) zaten belirlenmiştir ve oluşturma hızı uğruna bir daha değiştirilmemelidir.

şimdi, 3. kutu için -10 piksellik bir üst kenar boşluğu hayal edin. Bir miktar alan kazanmak için önceki tüm öğeleri yukarı kaydırmak yerine, tarayıcı kutu 3'ü yukarı iter, böylece z-endeksine bağlı olarak üstte (veya altta) oluşturulur. ) önceki öğeler. performans bir sorun olmasa bile, tüm öğeleri yukarı taşımak onları görünüm alanından çıkarmak anlamına gelebilir, bu nedenle mevcut kaydırma konumunun her şeyin tekrar görünür olması için değiştirilmesi gerekir.

Aynısı, hem negatif hem de pozitif kutu 3 için bir alt kenar boşluğu için de geçerlidir: önceden değerlendirilmiş öğeleri etkilemek yerine, yalnızca gelecek öğeler için yeni bir 'başlangıç ​​noktası' belirlenir. bu nedenle pozitif bir alt marj belirlemek aşağıdaki öğeleri aşağıya itecektir ; negatif olan onları yukarı itecektir.


EN İYİ cevap. Bu aynı zamanda "neden" i açıklarken, diğer yanıtlar yalnızca "nasıl" ı açıklıyor.
Amir Hossein Ahmadi

1
Bu cevap, neden daha iyi olduğunu anlamama yardımcı oldu. Teşekkürler @schellmax
iRamesh

3

Mutlak konumlandırma kullandığınız ve bir üst yüzde belirlediğiniz için, yalnızca margin-top .item nesnenizin konumunu etkileyecektir. Bunun yerine alt:% 50'yi kullanarak konumlandırdıysanız, ortalamak için margin-bottom -8px gerekir ve margin-top'ın hiçbir etkisi olmaz.

Kenar boşluğu, bir öğenin sınırlarını, sizin durumunuzda olduğu gibi, ya da komşu öğelere göre konumlandırma açısından etkiler. Kenar boşluğunun, üzerinde oturduğu öğenizin temelleri olduğunu hayal edin. Tipik olarak aynı boyuttadırlar, ancak dört kenarın herhangi birinde veya tamamında daha büyük veya daha küçük yapılabilir.

CSS'niz, tarayıcıya öğenizin üst kısmını kenar boşluğunun sayfanın% 50 altında bir noktaya yerleştirmesini söyler. Bununla birlikte, tüm öğeler tek bir piksel olmadığından, tarayıcının hangi kısmının sayfanın% 50'sini hizalayacağını bilmesi gerekir. Öğenin üst kısmını sıralamak için üst kenar boşluğunu kullanır. Varsayılan olarak bu, öğenin üstüyle aynı hizadadır, ancak bunu CSS ile değiştirebilirsiniz.

Sizin durumunuzda, ilk% 50, sayfanın ortasından başlayan öğenin üst kısmıyla sonuçlanır. Tarayıcı, negatif bir üst kenar boşluğu uygulayarak, 8px noktasını yukarıdan öğeye (yani ortasındaki çizgi)% 50 konumlandırma yeri olarak kullanır.

Alta pozitif bir kenar boşluğu uygularsanız, bu, tarayıcının alt kısmı öğenin kendisinden uzağa konumlandırmak için kullandığı çizgiyi genişleterek, onunla aşağıdaki herhangi bir bitişik öğe arasında bir boşluk bırakarak veya konumlandırmaya dayalıysa kesinlikle yerleştirildiği yeri etkiler. alt.


+1. Mantıklı ... Görselleştirmeyi tamamlamak için görsel ipuçlarıyla zenginleştirmek harika olurdu .
Doktora

3

Bu soruya iyi yanıt verilip verilmediğini merak ediyorum: css marjları nasıl çalışıyor ve neden bu margin-top: -5; margin-bottom ile aynı değildir: 5 ;?

Kenar boşluğu, elemanın çevresine olan mesafedir. margin-top, "... öğenin 'kutusunun' üst 'tarafından' ve 'kutunun' alt 'kenarından' olan margin-altından ölçtüğümüz için çevreden uzaklık" diyor. Ardından kenar boşluğu: 5; üst 'yan' çevre ile ilgilidir, bu durumda -5; üst 'taraftan' yaklaşan herhangi bir şey elemanın üst 'tarafı' 5 ve kenar-alt: 5 ile üst üste gelebilir; eleman alt 'tarafı' ile çevre arasındaki mesafe 5'tir.

Temelde bu, ancak kayan öğelerden ve benzerlerinden etkilenir: http://www.w3.org/TR/CSS2/box.html#margin-properties .

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

Düzeltilmeyi bekliyorum.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.