BFC是什么
BFC(Block Formatting Context,块级格式上下文) 是Web页面的可视化CSS渲染的一部分,是块盒子的布局过程发生的区域,也是浮动元素与其他元素交互的区域。
创建BFC的方式
-
根元素(
<html>
) -
浮动元素(元素的
float
不是none
) -
绝对定位元素(元素的
position
为absolute
或fixed
) -
行内块元素(元素的
display
为inline-block
) -
overflow
计算值(Computed)不为visible
的块级元素 -
弹性元素(
display
为flex
或inline-flex
元素的直接子元素) -
网格元素(
diaplay
为grid
或inline-grid
元素的直接子元素) -
display
值为flow-root
的元素 -
表格单元格(元素的
display
为table-cell
,HTML表格单元格默认为该值) -
表格标题(元素的
display
为 `table-caption表格单元格默认为该值) -
匿名表格单元格元素(元素的
display
为table
、table-row
、table-row-group
table-header-group
、table-footer-group
(分别是HTML table、row、tbody、thead、tfoot 的默认属性)或inline-table
) -
多列容器(元素的
column-count
或column-width
不为auto
,包括column-count
为1
) -
column-span
为all
的元素始终会创建一个新的BFC,即使该元素没有包裹在一个多列容器中(标准变更,Chrome bug)。 -
contain
值为layout
、content
或 paint 的元素
块级格式化上下文对浮动定位与清除浮动都很重要。浮动定位和清除浮动时只会应用于同一个BFC内的元素。浮动不会影响其它BFC元素的布局,而清除浮动只能清除同一BFC种在它前面的元素的浮动。外边距折叠(Margin collapsing)也只会发生在属于同一BFC的块级元素之间 。
BFC特性
- 内部box会在垂直方向,挨个放置
- box垂直方向的距离由margin决定,在一个BFC中,两个相邻的会计盒子的垂直外边距会产生折叠
- 在BFC中,没一个盒子的左外边缘(margin-left)会触碰到容器的左内边缘(border-left)(对于从右到左的格式来说,则触碰到右边缘)
- 形成了BFC的区域不会与 float box重叠
- 计算BFC高度时,浮动元素页参与计算
BFC范例
外边距塌陷
<div class="box"></div>
<div class="box"></div>
.box {
width: 100px;
height: 100px;
background-color: lightcoral;
margin: 100px;
}
从图中可以看到,两个 <div>
之间的间距是100px,而不是100+100=200px,这就是外边距折叠/塌陷。
创建新的BFC避免两个相邻 <div>
之间的外边距合并问题。
<div class="box"></div>
<div class="outer">
<div class="box"></div>
</div>
.box {
width: 100px;
height: 100px;
background-color: lightcoral;
margin: 100px;
}
.outer {
overflow: hidden;
}
高度塌陷
浮动的元素会脱离普通文档流,导致浮动元素的高度不参与父元素的高度计算,即常说的高度塌陷
<div class="outer">
<div class="inner"></div>
</div>
.outer {
border: 2px solid #000;
}
.inner {
float: left;
width: 100px;
height: 100px;
background-color: lightblue;
}
从图中可以看到,父元素的高度包含了上下边框高度,而不包含浮动的子元素高度。想要浮动的子元素也参与到父元素的高度计算中,在父元素上创建一个BFC即可。
.outer {
border: 2px solid #000;
overflow: hidden;
}
.inner {
float: left;
width: 100px;
height: 100px;
background-color: lightblue;
}
元素与浮动元素重叠
<div class="outer">
<div id="box1"></div>
<div id="box2">
我是一个没有设置浮动, 也没有触发 BFC 的元素。我是一个没有设置浮动,
也没有触发 BFC 的元素。我是一个没有设置浮动, 也没有触发 BFC 的元素。
</div>
</div>
.outer {
width: 300px;
font-size: 20px;
}
#box1 {
float: left;
width: 100px;
height: 100px;
background-color: lightblue;
}
从图中可以看到,第二个元素与浮动元素重叠,但文本信息不会被浮动元素覆盖,产生了文字环绕的效果。如果想避免元素被覆盖,可为第二个元素生成BFC。这种写法适合“左文右图”的布局
.outer {
width: 300px;
font-size: 20px;
}
#box1 {
float: left;
width: 100px;
height: 100px;
background-color: lightblue;
}
#box2 {
overflow: hidden;
}
PS:参考自MDN