为何在父元素创建新Block Formatting Context无法禁用外边距折叠?
为什么父元素创建BFC无法禁用子元素之间的外边距折叠?
这个问题其实涉及到BFC(块级格式化上下文)和外边距折叠的具体规则,我来给你拆解清楚:
首先要明确两个核心点:
父元素创建BFC的作用范围
父容器设置overflow: hidden或float创建BFC,它解决的是父元素与第一个/最后一个子元素之间的外边距折叠——比如如果父元素没有padding、border,子元素的margin会“溢出”到父元素外部,和父元素外面的元素产生折叠,这时候父元素的BFC就能把子元素的margin“包裹”在自己内部,阻止这种溢出折叠。但它不会影响同一个BFC内部的子元素之间的外边距折叠。子元素之间的外边距折叠规则
正常流中的块级元素,只要处于同一个BFC里,垂直方向的外边距就会发生折叠(取两者的最大值)。你的例子里,h1和h2都在.container这个BFC内部,属于正常流的块级元素,所以它们的margin-bottom(h1)和margin-top(h2)会折叠成10px,而不是叠加成20px。
那为什么给单个h元素加float能禁用折叠?
因为设置float的元素会脱离正常流,并且自身会创建一个新的BFC。这时候:
- 浮动元素不再属于原容器的正常流,所以和其他正常流的块级元素(比如另一个没浮动的h元素)不会发生外边距折叠;
- 如果两个h元素都浮动,它们属于各自的BFC,彼此之间的外边距也不会折叠,而是会叠加显示。
举个直观的验证:
如果给你的.container加一点padding: 1px,你会发现父元素和子元素的margin不再溢出,但h1和h2之间的间距还是10px(折叠后的结果);而如果给h1和h2都加上float: left; width: 100%;,它们之间的间距就会变成20px(两个margin叠加)。
总结一下:
- 父元素BFC:管的是父与子的margin溢出折叠;
- 子元素之间的margin折叠:需要让它们不在同一个正常流BFC里,比如给子元素加
float、position: absolute、display: inline-block(这些都会触发子元素自身创建BFC),或者把每个子元素分别放到独立的BFC容器中,才能阻止折叠。
内容的提问来源于stack exchange,提问作者user31782
相关产品推荐
相关产品推荐

