2

CSS 2.1 规范,关于折叠边距的第 8.3.1 节指出:

建立新块格式化上下文的元素的边距(例如浮动和具有“溢出”而不是“可见”的元素)不会与它们的流入子代一起折叠。

我花了一段时间才意识到块格式化上下文是由父级建立并应用于子级的上下文,因此要有所不同,必须在父元素上调整浮动或溢出属性(而不是给孩子们)。

在下面的代码片段中,相邻子 div 元素的边框高度折叠,因此任何两个子 div 元素之间的垂直间距为 max(20px, 20px) = 20px 而不是 20px + 20px = 40px,并且第一个子元素和父 div 以及最后一个子元素和父 div 之间的 max(20px, 0px) = 20px 而不是 20px + 20px = 40px。请注意,与 CSS 2.1 规范一样,水平方向不会出现折叠。

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Test</title>
<style type="text/css">
* { margin: 0; border: 0; padding: 0; }
</style>
</head>
<body style="background: green;">
  <div id="wrapper" style="width: 400px; background: black;
                           /* overflow: hidden; *//* float: left; */">
    <div id="box1" style="margin: 20px; height: 100px; background: red;">
    </div>
    <div id="box2" style="margin: 20px; height: 100px; background: blue;">
    </div>
    <div id="box3" style="margin: 20px; height: 100px; background: red;">
    </div>
    <div id="box4" style="margin: 20px; height: 100px; background: blue;">
    </div>
  </div>
</body>
</html>

情况1

如果红色 box1 元素的上边距没有与其父元素折叠,这样的边距不会将黑色背景推到边距下方,并且红色 box1 的边距将叠加在父元素的黑色背景上。类似的论点适用于底部的蓝色 box1 元素。

现在,正如 CSS 2.1 规范所提到的,如果“float:left;”中的任何一个 或“溢出:隐藏;” 包含 div 的部分被注释掉,然后是父元素的顶部和底部边框(在本例中为 0)和第一个子元素的顶部(在本例中为 10px)边框,以及底部(在本例中为 10px ) 底部孩子的边框,被分开,产生如下所示的结果:

在此处输入图像描述

现在,问题来了:

将这条规则引入 CSS 的理由是什么?这只是一个随机的决定,还是受到一些真实的、实际的例子的启发?(知道这也有助于我记住规则,除了满足我的好奇心)。

谢谢。

4

1 回答 1

2

我能给出的唯一合理的解释是块格式化上下文是原子的,从某种意义上说,一个块格式化上下文中的框永远不会与另一个块格式化上下文中的框交互。这个关于折叠边距的规则似乎与浮动永远不会侵入其他块格式化上下文或将它们自己的块格式化上下文退出到祖先块格式化上下文的规则相同。

对此进行扩展:建立新块格式化上下文的盒子的流入后代参与该盒子的块格式化上下文,而盒子本身参与在布局树中更高位置建立的块格式化上下文。因此,盒子本身的边距预计会与同一块格式化上下文中的盒子一起折叠,但不会与后代盒子一起折叠。

第 9.4.1 节似乎支持这一点:

块格式化上下文中相邻块级框之间的垂直边距折叠。

请注意,它说的是“块格式化上下文中的相邻块级框”——这意味着边距不会跨块格式化上下文折叠的事实是块格式化上下文的固有属性。但这只是我对规范的解释;我不是作者,所以我不能确定这是否是预期的意思。

于 2016-05-27T00:43:41.470 回答