CSS中的负边距如何工作,为什么会这样(margin-top:-5!= margin-bottom:5)?


108

垂直定位元素的常见技巧是使用以下CSS:

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

当您在指标视图(如Chrome)中看到以下内容时:

在此处输入图片说明

但是,当您将鼠标悬停在元素上时,即没有边界显示,即边界在边界“外部”并且可以可视化。但是不会出现负利润。它们的外观如何以及与众不同的原因是什么?

为什么margin-top:-8px 不一样 margin-bottom:8px

因此,负边距的工作原理以及其背后的直觉是什么。他们如何“碰撞”(如果有margin-top < 0)一件物品?

Answers:


89

负边距在CSS中是有效的,了解它们的(顺应性)行为主要是基于Box模型和边距折叠。尽管某些情况更为复杂,但在研究规范后可以避免很多常见的错误。

例如,示例代码的渲染受css规范的指导,如计算绝对定位的非替换元素的高度和边距中所述。

如果要进行图形表示,则可能需要这样的代码(不按比例缩放):

负上边距

保证金箱丢失8px的顶部,但是这并不影响内容和填充盒。因为您的元素是绝对定位的,所以将元素向上移动8px不会对布局造成任何进一步的干扰;静态流入内容并非总是如此。

奖金:

仍然需要说服,阅读规范是去(而不是这样的文章是这样)?我看到您正在尝试使元素垂直居中,那么为什么必须设置margin-top:-8px;而不是margin-top:-50%;

好吧,CSS的垂直居中比应该的难。以%设置顶部底部边距时,该值始终以相对于包含块的宽度的百分比计算。这是一个常见的陷阱,在w3 docos之外很少描述该怪癖


84

我将尝试以视觉方式进行解释:

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

边界是元素外部的间距,就像填充是元素内部的间距一样。

设置下边距可指示您希望当前块下方的距离。设置负顶边距表示您希望块上方具有负间距。负间距本身可能是一个令人困惑的概念,但是正负边距将内容压低,负负边距将内容压高。


2
+1我喜欢你的答案。可以通过注入onset和来改进它offset。的确如此,所以很多人在表示(肯定)时总是使用offset否定)这个词。如果您更新答案,此消息将自毁。干杯! onset
arttronics 2012年

1
margin-bottom: -8px;呢 为什么margin-bottom:-8px不一样margin-top:-8px
里克(Rick)

27

顶部空白为-8px表示比空白为0时高8px。

边距底边为8px表示它下方的东西如果边距为0,则比底边低8px。


1
我只是想使事情变得简单,但是我同意,这可能是我回答中最糟糕的事情!
Rich Bradshaw 2012年

2
我认为答案还不错。没有使用我们中一半人都无法理解的高度技术性答案。
Number945 '17

1
margin-bottom: -8px;呢 为什么margin-bottom:-8px不一样margin-top:-8px
里克(Rick)

22

这里已经提出了很多要点,但是尽管有很多关于浏览器如何完成边距渲染的信息,但是为什么尚未完全回答:

“为什么margin-top:-8px与margin-bottom:8px不同?”

我们还可以问的是:

为什么正面的底边利润不会“颠簸”前面的元素,而正面的底边利润却“颠簸”后面的元素?

因此,我们看到的是,边距的呈现方式有所不同,具体取决于边距应用于边的方式 -顶部(和左侧)边距与底部(和右侧)边距不同。

当(简单地)查看浏览器如何应用样式时,情况将变得更加清晰:元素在视口中自上而下渲染,从左上角开始(暂时保持垂直渲染,请记住,水平的一视同仁)。

考虑以下html:

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

类似于它们在代码中的位置,这三个方框在浏览器中显示为“自上而下”(保持简单,在此我们将不考虑ordercss3“ flex-box”模块的属性)。因此,每当将样式应用于框3时,就已经确定了先前元素的位置(对于框1和2),并且不应为了渲染速度而对其进行任何更改。

现在,假设框3的上边距为-10像素。浏览器不会向上移动所有前面的元素以收集一些空间,而是将框3向上推,因此将其呈现在上方(或下方),具体取决于z-index )任何前面的元素。即使性能不是问题,将所有元素上移也可能意味着将它们移出视口,因此必须更改当前滚动位置以使所有内容再次可见。

方框3的底边距也是如此(负数和正数):除了影响已经评估的元素外,仅确定即将出现的元素的新“起点”。因此,设置正的底部边距将使以下元素下降;负面的将推动他们。


最佳答案。这也解释了“为什么”,而其他答案仅解释了“如何”。
阿米尔·侯赛因·艾哈迈迪

1
这个答案帮助我理解了为什么更好。谢谢@schellmax
iRamesh

3

因为您使用了绝对定位并指定了最高百分比,所以只有margin-top会影响.item对象的位置。相反,如果您将其定位为使用bottom:50%,那么您将需要margin-bottom -8px来居中,而margin-top则无效。

边距影响元素边界的位置,这绝对取决于您的情况,或者相对于相邻元素。想象一下,边距是元素所在的基础。它们通常具有相同的大小,但可以在四个边缘中的任何一个或所有边缘上变大或变小。

CSS告诉浏览器将元素顶部的边距定位在页面下方50%处。但是,由于所有元素都不是单个像素,因此浏览器需要知道该元素的哪一部分要在页面的50%处对齐。为了使元素的顶部对齐,它使用了上边距。默认情况下,它与元素的顶部一致,但是您可以使用CSS对其进行更改。

在您的情况下,前50%将导致元素的顶部从页面的中间开始。通过应用负的上边距,浏览器使用从顶部到元素的8px点(即,跨其中间的线)作为定位在50%的位置。

如果对底部应用正边距,则会延长浏览器用来将底部放置在远离元素本身的位置的线,从而在底部和下面的任何相邻元素之间留出空隙,或者如果根据底部。


+1。很有道理...最好用视觉提示对其进行扩充,以完成可视化效果
博士2012年

3

我想知道是否已经很好地回答了这个问题:css margins如何工作,为什么margin-top:-5为什么?与margin-bottom:5不同吗?

裕度是与元素周围的距离。margin-top说:“ ...与周围环境的距离,即我们从元素'box'的顶部'侧面'测量的距离,margin-bottom是与'box'的底部'侧面'的距离。” 然后margin-top:5; 与顶部“侧面”周长有关,在这种情况下为-5;任何从顶部“侧面”接近的东西都可以与元素的顶部“侧面”重叠5,而margin-bottom:5; 表示元素底部“侧面”与周围之间的距离为5。

基本上,但受浮动元素等影响:http : //www.w3.org/TR/CSS2/box.html#margin-properties

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

我会得到纠正。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.