概述
1)什么是BFC
BFC,全称Block Formatting Content,译为“块级格式化上下文”。它是一个独立的渲染区域,只有block-level box参与,它规定了内部的block-level box如何布局。这个区域与外部毫不相干。
BFC是一个独立的布局环境,其中的元素布局不受外界的影响,并且在一个BFC中,块盒与行盒(行盒由一行中所有的内联元素组成)都会垂直沿着其父元素的边框排列。
2)什么是Box
Box是CSS布局的对象和基本单位。一个页面是由很多个Box组成的。元素的类型和display属性,决定了这个Box的类型。不同类型的Box会参与不同的Formatting Context(一个决定如何渲染文档的容器)。
block、list-item、table | 生成block-level box | 参与BFC |
inline、inline-block、inline-table | 生成inline-level box | 参与IFC |
run-in | CSS3中才有这个说明。 |
3)什么是Formatting Context
Formatting Context是W3C CSS2.1规范中的一个概念。它是页面中的一块渲染区域,并且有一套渲染规则,它决定了:
-
其子元素将如何定位;
-
与其他元素的关系和相互作用。
最常见的Formatting Context有BFC和IFC。
BFC布局规则
-
内部的Box会在垂直方向,一个接一个地放置。
-
Box垂直方向的距离由margin决定。
-
属于同一个BFC的两个相邻Box会发生margin合并。
-
每个盒子(行盒与块盒)的margin box左边与包含块的content box的左边相接触(如果是从右到左,则是两者的左边界相接触),即使存在浮动也是如此。
参考文献[1]中说是与包含块的border box的左边相接触,而CSS2.1规范说与包含块的左外边距相邻,但我实际测出来确是与content box的左边相接触。
-
BFC的区域不会与float box重叠。(见实验1)
-
计算BFC的高度时,浮动元素也会参与计算(清除浮动的原因)。(见实验2)
-
BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也是如此。(这句话可能是针对margin合并来说的,因为子元素导致产生BFC的Box发生了尺寸变化,也不是会影响外部的么,并且第4条也说明了外部的float box会影响BFC内部)
如何创建BFC
-
绝对定位的元素(即postion为absolute或fixed)
-
非块盒的块容器(即display为inline-block、table-cell和table-caption)
注:CSS3中加了flex和inline-flex两种。 -
overflow的值不是visible(即overflow为hidden、auto、scroll)。
BFC的作用
-
避免margin合并。根据规则2,属于同一个BFC的两个相邻Box会发生margin合并,因此我们可以设置两个不同的BFC来隔离,使其不发生margin合并。
-
自适应两栏布局。根据规则3,同一BFC中的浮动元素会被盒子忽略。再结合规则4,可以将浮动元素作为产生BFC元素的前兄弟元素,从而实现自适应两栏布局。
-
清除浮动。根据规则5,只要给浮动元素的父元素激活BFC就可以清除浮动。
因为BFC内部的元素和外部的元素绝对不会互相影响,因此, 当BFC外部存在浮动时,它不应该影响BFC内部Box的布局,BFC会通过变窄,而不与浮动有重叠。同样的,当BFC内部有浮动时,为了不影响外部元素的布局,BFC计算高度时会包括浮动的高度。避免margin重叠也是这样的一个道理。
附录
验证BFC区域不会与float盒重叠
基本代码:
<style>
.box1 {
width: 50px;
height: 50px;
float: left;
background: red;
}
.box2 {
width: 200px;
height: 100px;
position: absolute;
background: blue;
}
</style>
<div class="box1"></div>
<div class="box2"></div>
实验结果会出现重叠(左图)与不重叠(右图)两种情况:
实验结果如下:
box2创建BFC的方式 | 结果 |
---|---|
float | 不用试 |
position: abolute | 重叠 |
position: fixed | 重叠 |
display: inline-block | 不重叠 |
display: table-cell | 不重叠 |
display: table-caption | 不重叠 |
display: flex | 不重叠 |
display: inline-flex | 不重叠 |
overflow: hidden | 不重叠 |
overflow: auto | 不重叠 |
overflow: scroll | 不重叠 |
实验结论为:“BFC区域不会与float盒重叠”这一规律对绝对定位产生的BFC不适用,对其他方法产生的BFC适用。
验证浮动元素会参与BFC高度计算
基本代码:
<style>
.parent {
border: 5px solid red;
float: left;
background: red;
}
.son {
width: 200px;
height: 100px;
float: left;
background: blue;
}
</style>
<div class="parent">
<div class="son"></div>
</div>
实验结果如下:
parent创建BFC的方式 | 结果 |
---|---|
float | 参与 |
position: abolute | 参与 |
position: fixed | 参与 |
display: inline-block | 参与 |
display: table-cell | 参与 |
display: table-caption | 参与 |
display: flex | 参与 |
display: inline-flex | 参与 |
overflow: hidden | 参与 |
overflow: auto | 参与 |
overflow: scroll | 参与 |
需要注意的是,该规则只规定了浮动元素会参与BFC高度的计算,但没有规定参与BFC宽度的计算: