一、定义
MDN中是这样说的:块格式化上下文(Block Formatting Context,BFC) 是Web页面的可视化CSS渲染的一部分,是block块盒子的布局过程发生的区域,也是浮动float元素与其他元素交互的区域。
是不是看完之后,依然一脸懵逼.....反正我是(苦笑)。简单地说,BFC 就是某个元素的一个 CSS 属性,只不过这个属性不能被开发者显式的修改,拥有这个属性的元素对内部元素和外部元素会表现出一些特性,这就是BFC。
二、布局规则
- 内部的Box会在垂直方向,一个接一个地放置。
- Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠
- 每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
- BFC的区域不会与float box重叠。
- BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
- 计算BFC的高度时,浮动元素也参与计算
三、哪些元素会产生BFC?
- 根元素(
<html>
) - 浮动元素(元素的
float
不是none
) - 绝对定位元素(元素的
position
为absolute
或fixed
) - 行内块元素(元素的
display
为inline-block
) - 表格单元格(元素的
display
为table-cell
,HTML表格单元格默认为该值) - overflow的值不为visible(hidden、auto、scroll)
- 表格标题(元素的
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
) 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、解决外边距合并问题
当两个相邻块级子元素分属于不同的BFC时可以阻止margin重叠
操作方法:给其中一个div外面包一个div,然后通过触发外面这个div的BFC,就可以阻止这两个div的margin重叠,此处将外部div设置成 overflow: auto;
<body>
<div class="aside"></div>
<div class="text">
<div class="main"></div>
</div>
</body>
<style>
.aside {
margin-bottom: 20px;
width: 100px;
height: 150px;
background: #f66;
}
.main {
margin-top: 20px;
height: 200px;
background: #fcc;
}
.text {
/*盒子main的外面包一个div,通过改变此div的属性使两个盒子分属于两个不同的BFC,以此来阻止margin重叠*/
overflow: auto;
}
</style>
2、可以包含浮动元素——清除内部浮动
当两个子div都设置浮动后,父div不会将下面两个div包裹,但还是在父div的范围之内,
<body>
<div class="father">
<div class="child"></div>
<div class="child"></div>
</div>
</body>
.father {
border: 10px solid yellow;
}
.child {
float: left;
height: 200px;
width: 200px;
border: 10px solid tomato;
}
清除浮动:
给父div加上 overflow: hidden,触发父div的BFC属性,使下面的子div都处在父div的同一个BFC区域之内,此时已成功清除浮动。
3、自适应两栏布局,阻止元素被浮动元素覆盖
<body>
<div class="aside"></div>
<div class="main"></div>
</body>
body {
width: 900px;
position: relative;
}
.aside {
width: 400px;
height: 150px;
float: left;
background: yellow;
}
.main {
height: 200px;
background: #fcc;
}
aside设置成float:left后,内容会与main部分重叠,通过产生一个新BFC即可实现如下效果。
.main {
overflow: hidden;
height: 200px;
background: #fcc;
}