开发者社区 问答 正文

重提CSS中外边距折叠问题

避免父子元素边距折叠问题的方式分两类:
1.为父元素创建块级格式化上下文(BFC)(有一些元素是默认创建了 BFC 的,比如 body 元素),让它的子元素的 margin 值不影响父元素的 margin 值计算
2.将父元素与它的第一子元素「隔离开」,比如给父元素加 padding 或 border

但是当这个父元素是 body 元素的时候,奇怪的现象发生了,HTML 代码如下:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width">
    <title>testBodyMargin</title>
</head>
<body>
    <div class="father">
        <div class="son"></div>
    </div>
</body>
</html>

CSS 代码如下

html,
body,
div {
    margin: 0;
    padding: 0;
}
html, 
body {
    width: 100%;
    height: 100%;
}
html {
    background: #fff;
}
body {
    background: #a0cbed;
}

.father {
    overflow: hidden;
    width: 200px;
    height: 200px;
    margin: 50px;
    background: #008800;
}

.son {
    width: 50px;
    height: 50px;
    margin: 20px;
    background: #cc0000;
}

screenshot
此时 .father 和 body 元素的上外边距是折叠的,按照 BFC 的理论,如果 body 元素默认自动创建 BFC 的话, .fahter 元素的 margin-top 不应该影响到 body元素的外边距才对,这是疑问一

下面给 body 元素加一个 overflow 的 CSS 属性

body {
    overflow: hidden;
    background: #a0cbed;
}

现象与上图无差。

此时 .father 和 body 元素的上外边距仍然是折叠的,难道文章开头提到的避免折叠的方式一对于 body 元素无效了,这是疑问二

在此基础上,再给 html 元素加一个 overflow 的 CSS 属性

html {
    background: #fff;
    overflow: hidden;
}

奇迹发生了, 现象如图
screenshot
.father 和 body 元素的上外边距不折叠了,这是疑问三

求大神答疑解惑一下,谢谢!

展开
收起
杨冬芳 2016-06-02 14:26:22 2348 分享 版权
1 条回答
写回答
取消 提交回答
  • IT从业

    1.UA需要将root元素上的overflow属性置于视口之上;

    2.overflow扩散行为:当root元素是html元素且overflow为visible,而且html元素有body作为其子元素,UA则需要将第一个body之上的overflow属性应用于视口;

    3.用于视口的overflow: visible将被解析为overflow: auto

    4.overflow扩散行为将导致body的使用值为overflow: visible
    我们可以解释本节的三个用例里发生的事情了:

    1.给body加上overflow:hidden,无法触发BFC创建。
    解释:本用例中body {overflow:hidden} html {overflow: visible}(html为默认overflow),body的overflow:hidden被应用于视口,body的最终使用值为overflow:visible,因此body没有创建BFC。

    2.给body和html同时加上overflow:hidden,成功触发BFC创建。
    解释:本用例中body, html{overflow:hidden},html的overflow:hidden被用于视口,body的overflow计算值是hidden,因此创建了BFC。

    3.给body加上display:table、display:inline-block、position:absolute,成功触发BFC创建。
    解释:这些属性都导致body正常创建了BFC。

    LZ的用例2的body没有创建BFC因此没有避免margin折叠,用例3的body成功创建了BFC因此避免了margin折叠。

    最后,不要完全相信任何非一手的资料,尤其是中文资料

    2019-07-17 19:24:50
    赞同 展开评论
问答分类:
问答标签:
问答地址: