避免父子元素边距折叠问题的方式分两类:
为父元素创建块级格式化上下文(BFC)(有一些元素是默认创建了 BFC 的,比如 body 元素),让它的子元素的 margin 值不影响父元素的 margin 值计算
将父元素与它的第一子元素「隔离开」,比如给父元素加 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;
}
现象如图:
2# body在什么时候能够创建BFC?
测试一下常规的BFC创建方式:
给body加上overflow:hidden
http://jsfiddle.net/0yjxurfv/4/点击预览
结果:无法触发BFC的创建。
给body和html同时加上overflow:hidden
http://jsfiddle.net/0yjxurfv/5/点击预览
结果:可以触发BFC的创建。
给body加上display:table、display:inline-block、position:absolute
http://jsfiddle.net/0yjxurfv/6/点击预览
结果:可以触发BFC的创建。
为何呢?W3C CSS2.1中,BFC是这样被定义的:
Floats, absolutely positioned elements, block containers (such as inline-blocks, table-cells, and table-captions) that are not block boxes, and block boxes with 'overflow' other than 'visible' (except when that value has been propagated to the viewport) establish new block formatting contexts for their contents.
overflow:visible以外的块级元素将创建BFC,除非该值已经扩散到了视口。
(大部分中文资料都没有译出这个except,直到这个问题被提出,我也没有意识到这个except适用于哪个场景)
再寻找overflow:hidden的标准:
UAs must apply the 'overflow' property set on the root element to the viewport.
When the root element is an HTML "HTML" element or an XHTML "html" element, and that element has an HTML "BODY" element or an XHTML "body" element as a child, user agents must instead apply the 'overflow' property from the first such child element to the viewport, if the value on the root element is 'visible'.
The 'visible' value when used for the viewport must be interpreted as 'auto'.
The element from which the value is propagated must have a used value for 'overflow' of 'visible'.
按语序提取一下(这段颠三倒四颠鸾倒凤的话的)要点:
UA需要将root元素上的overflow属性置于视口之上;
overflow扩散行为:当root元素是html元素且overflow为visible,而且html元素有body作为其子元素,UA则需要将第一个body之上的overflow属性应用于视口;
用于视口的overflow: visible将被解析为overflow: auto
overflow扩散行为将导致body的使用值为overflow: visible
我们可以解释本节的三个用例里发生的事情了:
给body加上overflow:hidden,无法触发BFC创建。
解释:本用例中body {overflow:hidden} html {overflow: visible}(html为默认overflow),body的overflow:hidden被应用于视口,body的最终使用值为overflow:visible,因此body没有创建BFC。
给body和html同时加上overflow:hidden,成功触发BFC创建。
解释:本用例中body, html{overflow:hidden},html的overflow:hidden被用于视口,body的overflow计算值是hidden,因此创建了BFC。
给body加上display:table、display:inline-block、position:absolute,成功触发BFC创建。
解释:这些属性都导致body正常创建了BFC。
LZ的用例2的body没有创建BFC因此没有避免margin折叠,用例3的body成功创建了BFC因此避免了margin折叠。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。