为什么这种CSS边距顶部样式不起作用?


321

我尝试在另一个div内的div上添加边距值。除了最高值以外,其他所有方法都可以正常工作,它似乎被忽略了。但为什么?

我的期望:
我对保证金的期望是:50px 50px 50px 50px;

我得到的是:
我得到的保证金是:50px 50px 50px 50px;

码:

#outer {
    	width: 500px; 
    	height: 200px; 
    	background: #FFCCCC;
    	margin: 50px auto 0 auto;
    	display: block;
}
#inner {
    	background: #FFCC33;
    	margin: 50px 50px 50px 50px;
    	padding: 10px;
    	display: block;
}
<div id="outer">
  <div id="inner">
  	Hello world!
  </div>
</div>

W3Schools没有解释为什么保证金如此行事。


4
您是否尝试过浮动内部的?
公鸡2012年

6
嗡嗡声.. float:left;它可以工作...但是为什么需要这样做。我不希望它浮动。为什么左/右保证金起作用?
jamietelin 2012年

44
欢迎来到CSS边距折叠算法的有趣世界!
GordonM

10
W3Schools与W3CDocs ...我认为我们有一个赢家。:D
enderskill

15
jsFiddle,以节省下一个家伙25秒jsfiddle.net/kLeu9
CodyBugstein 2013年

Answers:


453

您实际上看到的是#inner元素的顶部边缘塌陷到元素的顶部边缘#outer,仅保留了#outer边缘完整(尽管未在图像中显示)。两个框的顶部边缘彼此齐平,因为它们的边距相等。

以下是W3C规范的相关要点:

8.3.1利润下降

在CSS中,两个或多个框(可能是也可能不是兄弟)的相邻边距可以合并形成一个边距。以此方式合并的边距被称为崩溃,并且合并后的边距称为崩溃边距

相邻的垂直边距崩溃[...]

当且仅当以下情况,两个边距相邻

  • 两者都属于流内块级框,它们参与相同的块格式上下文
  • 没有线框,没有间隙,没有填充和没有边框将它们分开
  • 都属于垂直相邻的框边,即形成以下对之一:
    • 盒子的上边距和第一个流入子元素的上边距

您可以执行以下任一操作来防止边距崩溃:

上述选项防止边距崩溃的原因是:

  • 浮动框与任何其他框之间的边距不会折叠(即使在浮动框及其流入子框之间也不会折叠)。
  • 建立新块格式上下文的元素(例如浮点数和具有“可见”以外的“溢出”的元素)的边距不会随其流入子元素而崩溃。
  • 内联阻止框的边距不会折叠(即使带有其流入子框也不会折叠)。

左右边距的行为符合您的预期,因为:

水平边距永远不会崩溃。



2
这个答案真是令人震惊!只是要添加的东西。您对w3c的引用说了这一点,但我现在才意识到。因此,为其他人清楚起见,您也可以给#outer一个边界。
driechel

浮动中的链接似乎已断开。
EP

@episanty:这就是您链接到评论时发生的情况。未链接。
BoltClock

我知道-只是想让你知道。由于您已启用♦,我认为您可能希望重新发表评论-或相应地更改您的帖子。顺便说一句,谢谢您的好回答。
EP

92

尝试display: inline-block;在内部div上使用。

#outer {
    width:500px; 
    height:200px; 
    background:#FFCCCC;
    margin:50px auto 0 auto;
    display:block;
}
#inner {
    background:#FFCC33;
    margin:50px 50px 50px 50px;
    padding:10px;
    display:inline-block;
}

6
好答案。如果能解释为什么此更改可以解决问题,那就更好了。
JohnFx 2012年

1
好吧,这很奇怪!为什么行得通?对于为什么它不如人们期望的那样起作用的逻辑解释是什么。左/右边距的作品没有display:inline-block;。使用时也要回过头来display:inline-block;,因为它会使div失去100%的宽度。
jamietelin 2012年

3
将其切换为inline-block会强制浏览器在放置div和其他规则后重新评估div的大小。
公鸡2012年

针对我的问题进行了尝试,取得了楼梯效果。
强尼

1
display:inline-block为我工作。非常感谢。
starkeen

24

@BoltClock提到的内容非常可靠。在这里,我只想为这个问题添加更多解决方案。检查这个w3c_collapsing margin。绿色部分是如何解决此问题的潜在思路。

解决方案1

浮动框与任何其他框之间的边距不会折叠(即使在浮动框及其流入子框之间也不会折叠)。

这意味着我可以添加float:left到任何#outer#inner demo1的

还请注意,float这会使auto保证金无效。

解决方案2

建立新块格式上下文的元素(例如浮点数和具有“可见”以外的“溢出”的元素)的边距不会随其流入子元素而崩溃。

比其他的visible,让我们把overflow: hidden进入#outer。而且这种方式看起来非常简单和体面。我喜欢。

#outer{
    width: 500px;
    height: 200px;
    background: #FFCCCC;
    margin: 50px auto;
    overflow: hidden;
}
#inner {
    background: #FFCC33;
    height: 50px;
    margin: 50px;
}

解决方案3

绝对定位的盒子的边缘不会塌陷(即使带有流入的盒子也不会塌陷)。

#outer{
    width: 500px;
    height: 200px;
    background: #FFCCCC;
    margin: 50px auto;
    position: absolute; 
}
#inner{
    background: #FFCC33;
    height: 50px;
    margin: 50px;
}

要么

#outer{
    width: 500px;
    height: 200px;
    background: #FFCCCC;
    margin: 50px auto;
    position: relative; 
}
#inner {
    background: #FFCC33;
    height: 50px;
    margin: 50px;
    position: absolute;
}

这两种方法将打破正常的流程 div

解决方案4

内联阻止框的边距不会折叠(即使带有其流入子框也不会折叠)。

与@enderskill相同

解决方案5

除非块中有间隙,否则流入的块级元素的下边距总是与其下一个流入的块级同级的上边距一起折叠。

这与问题无关,因为这是兄弟姐妹之间的崩溃边缘。它通常表示顶盒是否具有,margin-bottom: 30px而同级盒是否具有margin-top: 10px。它们之间的总边距30px40px

解决方案6

如果元素没有顶部边框,没有顶部填充且子元素没有间隙,则流入元素块元素的顶部边缘会以其第一个元素流入子块的顶部边缘折叠。

这非常有趣,我只可以添加一条顶部边框线

#outer{
    width: 500px;
    height: 200px;
    background: #FFCCCC;
    margin: 50px auto;
    border-top: 1px solid red;

}
#inner {
    background: #FFCC33;
    height: 50px;
    margin: 50px;

}

而且<div>默认情况下,Also 是块级的,因此您不必故意声明它。很抱歉,由于我的新手声誉而无法发布2个以上的链接和图片。至少您知道问题的根源是下次您看到类似的内容。


14

不知道为什么您的东西不起作用,但是您可以添加

overflow: auto;

到外部div。


大量的不同解决方案可以解决此问题。谢谢!该答案与@BoltClock的答案相结合,提供了有关此解决方案为何起作用的良好信息。
jamietelin 2012年

12

如果您将任何填充添加到#outer,则可以使用。

演示版

#outer {
    width:500px; 
    height:200px; 
    background:#FFCCCC;
    margin:50px auto 0 auto;
    display:block;
    padding-top:1px;
}

11

不确定原因,但将内部CSS更改为

display:inline-block;

似乎有效;


3

不会回答“为什么”(必须要有使边际崩溃的问题),但似乎最简单/最合乎逻辑的方法来做您要做的事情就是将其添加padding-top到外部div

http://jsfiddle.net/hpU5d/1/

次要注意事项- display:block;除非将代码中的其他内容告诉它不要阻塞,否则不必将div设置为。



2

我想将#inner div 的position属性设置为relative可能也有助于达到效果。但是无论如何,我都尝试将原始代码粘贴到IE9和最新的Google Chrome浏览器的问题中,并且它们已经产生了令人满意的效果,而无需进行任何修改。


2

使用padding-top:50px的外层div。像这样:

#outer {
    width:500px; 
    height:200px; 
    background:#FFCCCC;
    margin:50px auto 0 auto;
    display:table;}

注意:填充会增加div的大小。在这种情况下,如果您的div的大小很重要,那么我的意思是它是否必须具有特定的高度。将高度降低50像素。:

#outer {
    width:500px; 
    height:150px; 
    background:#FFCCCC;
    margin:50px auto 0 auto;
    display:table;}

1

您是否尝试过!重要,它将迫使一切:

margin:50px 50px 50px 50px !important;

-1

为了快速解决问题,请尝试将您的子元素包装成这样的div元素-

<div id="outer">
   <div class="divadjust" style="padding-top: 1px">
      <div id="inner">
         Hello world!
      </div>
   </div>
</div>

innerdiv的边距不会由于indiv 和div 1px之间的填充而崩溃。因此,从逻辑上讲,您将拥有额外的空间以及div的现有边距。outerinner1pxinner

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.