为什么这种CSS margin-top风格不起作用?

jam*_*lin 309 html css margin

我尝试在另一个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;
}
Run Code Online (Sandbox Code Playgroud)
<div id="outer">
  <div id="inner">
  	Hello world!
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)

W3Schools没有解释为什么保证金的行为方式.

Bol*_*ock 434

您实际上看到#inner元素的上边缘会折叠到元素的上边缘#outer,只留下#outer边距(尽管图中未显示).两个盒子的顶部边缘相互齐平,因为它们的边缘相等.

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

8.3.1折叠边距

在CSS中,两个或多个框(可能是也可能不是兄弟)的相邻边距可以组合形成单个边距.据说以这种方式组合的边距会崩溃,因此产生的合并边距称为折叠边距.

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

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

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

执行以下任何操作的原因可防止边距折叠:

是因为:

  • 浮动框和任何其他框之间的边距不会崩溃(甚至在浮动及其流入子代之间也不会).
  • 建立新块格式化上下文的元素的边距(例如浮点数和"溢出"除"可见"之外的元素)不会因其流入的子节点而崩溃.
  • 内联块方框的边距不会崩溃(甚至不包括它们的流入子代).

左边距和右边距的行为与预期的一样,因为:

水平边距永不崩溃.

  • 显然,[你不是唯一认为这是愚蠢的人](http://stackoverflow.com/questions/3069921/what-is-the-point-of-css-collapsing-margins)... (11认同)
  • 这个答案摇滚!只需添加一些东西.你对w3c的引用说了但我现在才意识到.所以为了让别人清楚你也可以给#outer一个边框. (2认同)

end*_*ill 84

尝试使用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;
}
Run Code Online (Sandbox Code Playgroud)

  • 好答案.如果它解释了为什么这个改变解决了问题会更好. (4认同)
  • 好吧,这太奇怪了!为什么这样有效?为什么它不能按预期工作的逻辑解释是什么?左/右边距无需“display:inline-block;”即可工作。使用“display:inline-block;”时还需要注意的是,您会丢失 div 上 100% 的宽度。 (2认同)
  • 将其切换为内联块会强制浏览器在放置div并应用其他规则后重新评估div的大小. (2认同)

Qia*_*ang 20

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

解决方案1

浮动框和任何其他框之间的边距不会崩溃(甚至在浮动及其流入子代之间也不会).

这意味着我可以添加float:leftdemo1#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;
}
Run Code Online (Sandbox Code Playgroud)

解决方案3

绝对定位的盒子的边缘不会坍塌(甚至没有流入的孩子).

#outer{
    width: 500px;
    height: 200px;
    background: #FFCCCC;
    margin: 50px auto;
    position: absolute; 
}
#inner{
    background: #FFCC33;
    height: 50px;
    margin: 50px;
}
Run Code Online (Sandbox Code Playgroud)

要么

#outer{
    width: 500px;
    height: 200px;
    background: #FFCCCC;
    margin: 50px auto;
    position: relative; 
}
#inner {
    background: #FFCC33;
    height: 50px;
    margin: 50px;
    position: absolute;
}
Run Code Online (Sandbox Code Playgroud)

这两种方法都会破坏正常的流量 div

解决方案4

内联块方框的边距不会崩溃(甚至不包括它们的流入子代).

与@enderskill相同

解决方案5

流入块级元素的下边缘总是与其下一个流入块级兄弟的上边缘折叠,除非该兄弟有间隙.

这与问题没什么关系,因为它是兄弟姐妹之间的崩溃边缘.它通常意味着一个顶盒有margin-bottom: 30px一个兄弟盒子margin-top: 10px.它们之间的总余量30px不是40px.

解决方案6

如果元素没有顶部边框,没有顶部填充,并且子节点没有间隙,则插入块元素的上边距将与其第一个流入块级子节点的上边距折叠.

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

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

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

}
Run Code Online (Sandbox Code Playgroud)

并且<div>默认情况下也是块级别,因此您不必故意声明它.很抱歉,由于我的新手声誉,我们无法发布超过2个链接和图片.至少你知道问题来自下次你看到类似的东西.


Bra*_*don 12

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

overflow: auto;

到外部的div.


har*_*ott 10

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

display:inline-block;
Run Code Online (Sandbox Code Playgroud)

似乎工作;


boo*_*sey 10

如果你添加任何填充#outer,它的工作原理.

演示

#outer {
    width:500px; 
    height:200px; 
    background:#FFCCCC;
    margin:50px auto 0 auto;
    display:block;
    padding-top:1px;
}
Run Code Online (Sandbox Code Playgroud)


Dav*_*ave 5

不回答“为什么”(必须是带有折叠边距的东西),但似乎做你想做的事情的最简单/最合乎逻辑的方法就是添加到外部padding-topdiv

#outer {
    width:500px; 
    height:200px; 
    background:#FFCCCC;
    margin:50px auto 0 auto;
    padding-top: 50px;
}
#inner {
    background:#FFCC33;
    margin:0px 50px 50px 50px;
    padding:10px;
}
Run Code Online (Sandbox Code Playgroud)
<div id="outer">
    <div id="inner">
        Hello world!
    </div>
</div>
Run Code Online (Sandbox Code Playgroud)

小注意事项 - 没有必要将 div 设置为 ,display:block;除非代码中有其他内容告诉它不要被阻止。


Art*_*nin 5

创建新的块格式化上下文

您可以display: flow-root在父元素上使用,以防止在创建新的块格式上下文时包含元素的边距折叠。

将overflow属性的值更改为auto或使用flexbox将具有相同的效果。

https://codepen.io/rachelandrew/pen/VJXjEp