这是经典的折叠边距行为。
编写 CSS 规范的人认为这是一个好主意,可以防止边距创建过多的空白。如果没有这种行为,控制块元素之间的边距/空白将需要做更多的工作。
参考:
CSS2 规范 - http://www.w3.org/TR/CSS2/box.html#collapsing-margins
安迪巴德文章 - http://andybudd.com/archives/2003/11/no_margin_for_error/
Eric Meyer 文章 - http://www.complexspiral.com/publications/uncollapsing-margins/
为什么崩溃的边距是一个好主意
折叠边距是 CSS 盒模型的一个特性,它构成了视觉格式化模型的基本工作单元,它使我们能够拥有一个合理的环境来开发网页。
在设计 CSS 规范时,作者必须平衡如何编写规则,例如:margin: 1.0em
以及这些规则如何在需要从上到下和从左到左布局内容块的 CSS 格式化引擎中工作-right(至少在西欧语言中)。
按照上面引用的 Eric Meyer 文章的思路,假设我们有一系列段落,其页边距样式如下:
p { margin: 1.00em; }
对于我们这些曾经看到段落之间有规则间距的打印页面的人来说,人们会期望任何两个相邻段落之间的间距为 1.00em。人们还希望第一段前面有 1.00em 的边距,最后一段后面有 1.00em 的边距。这是对简单 CSS 规则的p
行为方式的合理预期,也许是简化的预期。
然而,对于构建解释简单p
规则的 CSS 引擎的程序员来说,有很多歧义需要解决。如果人们期望 CSS 规则的打印页面解释,那么这自然会导致collapsing margin
行为。所以程序员想出了一个更复杂的规则,比如:如果有两个相邻的p
标签具有上下边距,则将边距合并在一起。
现在这引出了一个问题,您如何“将边距合并在一起”?相邻顶部和底部边距的最小值或最大值,两者的平均值?第一个元素的边距总是?如果你有除p
's 之外的其他块元素怎么办?如果您添加边框或背景?接下来是什么?
最后,您如何计算所有这些边距设置,这样您就不必多次遍历整个 HTML 元素集(这会使复杂的页面加载缓慢,尤其是在早期的浏览器中)?
在我看来,折叠边距为一个复杂的问题提供了一个解决方案,它平衡了为边距编写 CSS 规则的便利性、用户对打印页面如何在我们的印刷遗产中布局的期望,最后,提供了一个可以在内部实现的程序浏览器存在的编程环境。