内部div的margin会影响包含它的div的margin

21

我有一个包含内部div的外部div。

HTML

<div id="container">
  <div id="inner"></div>
</div>

CSS

#container {
    width: 100px;
    height: 100px;
    background-color: red;
}
#inner {
    margin: 30px;
    width: 40px;
    height: 40px;
    background-color: black;
}

Fiddle

http://jsfiddle.net/8xUTJ/4/

我希望这个代码能够让一个小黑盒子垂直和水平居中出现在一个大的红色盒子内。但实际上,黑盒子卡在了红盒子的顶部,并且红盒子有margin-top。请问有人可以解释下CSS在这里到底做了什么?

5个回答

30
#container div 中添加 overflow:autojsFiddle example 或者
#container div 添加边框。
你可以在W3C中了解更多关于折叠边距行为的内容。

这个超级奇怪的CSS“margin collapse”逻辑背后是否有一些隐藏的原因???它似乎是我遇到过最反直觉的行为,我敢打赌数百万开发人员已经掉进了这个陷阱,并尝试了不必要的解决方法,如填充、溢出等,导致不必要的副作用...请原谅我的直言不讳,但有时候CSS似乎是最愚蠢的语言之一。 - Gilad Barner

15
虽然提供的解决方案是可行的,但没有人解释这个问题。它被称为边距折叠,在多种情况下会发生。
情景1 - 这些项目之间只会相距30像素,因为边距会合并在一起,并且较大的边距会占优势。
<div style="margin-bottom: 20px"></div>
<div style="margin-top: 30px"></div>

场景2 - (您的场景)内部框架的边距溢出外部框架。

<div class="outer">
    <div style="margin-top: 20px"></div>
</div>

解决方案是给外层盒子添加一些padding或border(如其他人所建议的)。通常情况下,我在外层盒子上使用以下CSS来解决这种情况:

.outer {
    margin-top: -1px;
    border-top: 1px solid transparent;
}

4
这里的解释比简单的链接更易于理解。 - fuxia
@toscho - 如果简短明了当然可以,但是没有必要粘贴整个折叠边距的解释,一个链接就足够了。而且我相信W3C不会很快消失。 - j08691

3

2
首先,#container 具有 margin-top:0,而 #inner 具有 margin-top:30px。这些元素之间的关系是父子关系。
如果没有边框、内边距、行内内容或清除来分隔块的 margin-top 和其第一个子块的 margin-top,或者没有边框、内边距、行内内容、高度、最小高度或最大高度来分隔块的 margin-bottom 和其最后一个子块的 margin-bottom,则这些 margin 会发生折叠。折叠的 margin 最终出现在父元素外部。
Margin 折叠意味着这些 margin 组合成一个单一的 margin,其大小为组合到其中的 margin 中的最大值。
即使是零 margin,这些规则也适用,因此第一个/最后一个子元素的 margin 最终会出现在其父元素外面(根据上述规则),无论父元素的 margin 是否为零。
这就是为什么你会在 fiddle 中看到应用了 30px 的顶部 margin 位于 #container 元素的外部的原因。

1

检查这个fiddle

你需要使用float来使内部的div正常工作

#inner {    
    margin:30px;
    float:left;   /* give float */
    width: 40px;
    height: 40px;
    background-color: black;
 }​

否则给
属性overflow:auto

请查看fiddle


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接