CSS中的负边距如何工作以及为什么(保证金最高:-5!=保证金底部:5)?

时间:2012-07-15 20:06:27

标签: css margin

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

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

在公制视图中看到,就像在Chrome中看到的那样:

enter image description here

但是,当您将鼠标悬停在元素上时,没有描绘视觉边距,即边距位于边界“外部”并且可以显示。但负利润率并未出现。它们看起来如何,它与它有什么不同?

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

负面利润如何运作以及它们背后的直觉是什么呢?他们如何“提升”(如果是margin-top < 0)项目?

8 个答案:

答案 0 :(得分:77)

负边距在css中有效,并且理解其(合规)行为主要基于box model和边距折叠。虽然某些情况比较复杂,但在研究规范后可以避免许多常见错误。

例如,您的示例代码的呈现由css规范指导,如calculating heights and margins for absolutely positioned non-replaced elements中所述。

如果我要进行图形表示,我可能会选择这样的(不按比例):

negative top margin

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

<强>加成:

还是需要说服阅读规范 的方式(而不是articles like this)?我看到你试图将元素垂直居中,为什么你必须设置margin-top:-8px;而不是margin-top:-50%;

好吧,CSS中的垂直居中是harder than it should be。在%中设置均匀顶部底部边距时,该值将计算为a percentage always relative to the width of the containing block。这是一个常见的陷阱,而且在w3 docos之外很少描述这个怪癖

答案 1 :(得分:69)

我会尝试用肉眼解释它:

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

答案 2 :(得分:28)

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

设置下边距表示您想要在当前块下方的距离。设置负上边距表示您希望在块上方显示负间距。负间距本身可能是一个令人困惑的概念,但只是积极的上边距推动内容的方式,负的上边距会拉高内容。

答案 3 :(得分:19)

-8px的保证金最高意味着它比0保证金高8px。

8px的保证金底部意味着如果它有0保证金,它下面的东西将比8px更低。

答案 4 :(得分:15)

这里已经提出了很多好处,但是有很多关于 如何 浏览器完成边距渲染的信息, why < / em> 还没有完全回答:

  

“为什么保证金最高:-8px与保证金底部不同:8px?”

我们也可以问的是:

  

为什么前面的元素没有正向底部边缘'突然上升',而正面的利润空间“突然”跟随元素?

所以我们看到的是,边距的渲染存在差异,具体取决于它们应用于哪一侧 - 顶部(和左侧)边距与底部(和右侧)边距不同。

当(简化)查看浏览器如何应用样式时,事情变得越来越清晰:元素在视口中自上而下呈现,从左上角开始(现在让我们坚持使用垂直渲染,保持记住水平的一个被处理相同)。

考虑以下html:

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

类似于他们在代码中的位置,这三个框在浏览器中显示为“自上而下”(保持简单,我们在此不会考虑css3的order属性'flex-盒子模块)。因此,每当样式应用于方框3时,前一个元素的位置(对于方框1和2)已经确定,并且为了提高速度不应再改变。

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

同样适用于方框3的底部边距,包括负面和正面:不是影响已经评估的元素,而是确定即将到来的元素的新“起点”。因此设置正的底部保证金将推动跟随元素;否定的将推动他们。

答案 5 :(得分:3)

由于您使用了绝对定位并指定了最高百分比,因此只有margin-top会影响.item对象的位置。如果你用底部定位它:50%,那么你需要margin-bottom -8px来使它居中,而margin-top将没有效果。

边距会影响元素的边界,无论是在您的情况下,还是相对于相邻元素,都会对其进行定位。想象一下,保证金是您所在元素的基础。它们通常与它的尺寸相同,但可以在四个边缘的任何一个或全部上变大或变小。

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

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

如果你在底部应用一个正边距,这会扩展浏览器用来将底部放置在远离元素本身的位置,在它与下面的任何相邻元素之间留一个间隙,或影响它放置的位置绝对如果基于底部的定位。

答案 6 :(得分:3)

我想知道这个问题是否得到了很好的回答:css边距是如何工作的,为什么它是边缘上限:-5;与margin-bottom不同:5;?

边距是元素周围的距离。 margin-top表示“......我们从元素'盒'的顶部'侧'测量距离周围的距离,而边距底部是'盒子'的底部'侧'的距离”。保证金最高:5;关注顶部'侧'外围,在这种情况下为-5;从顶部'侧'接近的任何东西都可以与元素的顶部'侧'重叠5,边距底部: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/

我有待纠正。

答案 7 :(得分:0)

只是为了表达与上述出色答案不同的措辞,因为这有助于我对负利润率有一个直观的理解:

元素上的负边距允许它吃掉其父容器的空间。

在底部添加(正)边距不允许元素这样做 - 它只会推回下方的任何元素。