定义:
块格式化上下文(Block Formatting Context,BFC) 是Web页面的可视化CSS渲染的一部分,是块盒子的布局过程发生的区域,也是浮动元素与其他元素交互的区域。
BFC的布局规则如下:
1.内部的盒子会在垂直方向,一个个地放置; 2.盒子垂直方向的距离由margin决定,属于同一个BFC的两个相邻Box的上下margin会发生重叠; 3.每个元素的左边,与包含的盒子的左边相接触,即使存在浮动也是如此; 4.BFC的区域不会与float重叠; 5.BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之也如此; 6.计算BFC的高度时,浮动元素也参与计算。
以下行为会触发BFC
官方:
根元素(<html>) 浮动元素(元素的 float 不是 none) 绝对定位元素(元素的 position 为 absolute 或 fixed) 行内块元素(元素的 display 为 inline-block) 表格单元格(元素的 display为 table-cell,HTML表格单元格默认为该值) 表格标题(元素的 display 为 table-caption,HTML表格标题默认为该值) 匿名表格单元格元素(元素的 display为 table、table-row、 table-row-group、table-header-group、table-footer-group(分别是HTML table、row、tbody、thead、tfoot的默认属性)或 inline-table) overflow 值不为 visible 的块元素 display 值为 flow-root 的元素 contain 值为 layout、content或 paint 的元素 弹性元素(display为 flex 或 inline-flex元素的直接子元素) 网格元素(display为 grid 或 inline-grid 元素的直接子元素) 多列容器(元素的 column-count 或 column-width 不为 auto,包括 column-count 为 1) column-span 为 all 的元素始终会创建一个新的BFC,即使该元素没有包裹在一个多列容器中(标准变更,Chrome bug)。
资源:
1.浮动元素:float 除 none 以外的值。 2.绝对定位元素:position (absolute、fixed)。 3.display 为 inline-block、table-cells、flex。 4.overflow 除了 visible 以外的值 (hidden、auto、scroll)。
解决方案:
使用 overflow 来创建一个新的BFC,是因为 overflow 属性告诉浏览器你想要怎样处理溢出的内容。
案例
demo1:自适应两栏布局
我们先定义两个div:
<div class="aside"></div> <div class="main"></div>
然后定义css:
div { width:300px; } .aside { float: left; width: 100px; height: 150px; background: black; } .main { height:200px; background-color:red; }
效果图如下:
分析:
这正满足了规范的第三条: 每个元素的左边,与包含的盒子的左边相接触,即使存在浮动也是如此。 所以如果我们需要将黑色区域撑到红色的左边,就需要利用规范的第四条: BFC的区域不会与float重叠。 也就是说我们需要创造BFC区域。我们通过将红色区域的overflow设为hidden来触发BFC:
.main { height:200px; overflow:hidden; background-color:red; }
效果如下:
demo2:清除内部浮动
首先是父div套子div
<div class="parent"> <div class="child"></div> </div>
然后是css:
.parent { width:300px; border:1px solid black; } .child { float:left; width:100px; height:100px; border:1px solid red; }
效果如下:
可以看到,父div压根就没有被撑开。 我们再回顾一下BFC规范中的第六条: 计算BFC的高度时,浮动元素也参与计算。 所以我们需要将父div触发为BFC,也就是将其overflow设为hidden:
.parent { width:300px; overflow:hidden; border:1px solid black; }
效果如下:
可以看到父div已经撑开了。
demo3:margin重叠问题
先定义两个垂直的div:
<div class="p"></div> <div class="p"></div>
然后定义margin:
.p { width:200px; height:50px; margin:50px 0; background-color:red; }
可以看到margin重叠后的效果:
我们再看看BFC规范的第二条: 盒子垂直方向的距离由margin决定,属于用一个BFC的两个相邻Box的上下margin会发生重叠。 说明两者属于同一个BFC,所以我们需要两个div不属于同一个BFC。 为第二个div套一个父亲div,然后讲其overflow设为hidden来激活一个BFC就可以使margin不再重叠。
html:
<div class="p"></div> <div class="wrap"> <div class="p"></div> </div>
css:
.wrap { overflow:hidden; }
效果如下:
相关资料: