1.背景介绍
BFC全称是Block Formatting Context,是CSS2.1规范定义的,关于CSS渲染定位的一个概念。它的定位体系属于常规文档流。BFC(Block formatting context)直译为"块级格式化上下文"。它是一个独立的渲染区域,只有Block-level box参与,它规定了内部的Block-level Box如何布局,并且与这个区域外部毫不相干。要理解BFC,先了解视觉格式化模型。
视觉格式化模型(visual formatting model),是CSS中的一个概念,用来处理文档并将它显示在视觉媒体上的机制。 我们常说的盒模型只是CSS视觉格式化的一部分。Box 是 CSS 布局的对象和基本单位,一个页面可以想象成由很多个 Box 组成的。元素的类型和 display 属性,决定了这个 Box 的类型。 不同类型的 Box, 会参与不同的 Formatting Context(格式化上下文), 因此Box内的元素会以不同的方式渲染。BFC是页面中的一块渲染区域,并且有一套渲染规则, 它决定了其子元素将如何定位,以及和其他元素的关系和相互作用。
最常见的 Formatting context 有 Block fomatting context (简称BFC)和 Inline formatting context (简称IFC)。
block-level box:display 属性为 block, list-item, table 的元素,会生成 block-level box。并且参与 block fomatting context(块格式化上下文);
inline-level box:display 属性为 inline, inline-block, inline-table 的元素,会生成 inline-level box。并且参与 inline formatting context;
2.知识剖析
BFC( Block formatting contexts)的布局规则
1. 在BFC中的盒子是block-level box,其排列方式是从包含块顶部开始,垂直向下排列。
2.相邻两个盒子之间的垂直间距由margin决定,在一个BFC内部的两个block-level box之间的垂直margin是折叠的。
3. BFC的区域不会与float box重叠。内部元素不受外部元素影响
4.计算BFC的高度时,考虑BFC所包含的所有元素,连浮动元素也参与计算。
5.浮动的BOX区域不会叠加到BFC上。
6.参与BFC的布局的只有普通文档流normal flow中的块级盒,而float、position值不为relative\static的元素不参与BFC的布局。
BFC的范围
MDN 对BFC范围的描述是:
A block formatting context contains everything inside of the element
creating it that is not also inside a descendant element that creates a new block formatting
context.
意思一个BFC包含创建该上下文元素的所有子元素,但不包括创建了新BFC的子元素的内部元素。就是说一个BFC中,如果一个子元素触发了BFC 那么这个子元素内部的元素不受外部BFC的影响。这就是BFC的一个重要属性,让处于BFC内部的元素与外部的元素相互隔离,使内外元素的定位不会相互影响。BFC的这个特性通常用于清除浮动元素的影响
3.常见问题
3.1 如何触发BFC?
3.2 BFC的作用
4 解决方案
4.1创建BFC
BFC的创建方法
1.根元素;
2.浮动 (元素的float不为none);
3.绝对定位元素 (元素的position为absolute或fixed);
4.行内块inline-blocks(元素的 display: inline-block);
5.表格单元格(元素的display: table-cell,HTML表格单元格默认属性);
6. overflow的值不为visible的元素;
7.弹性盒 flex boxes (元素的display: flex或inline-flex);
其中,最常见的就是overflow:hidden; float:left/right; position:absolute。也就是说,当这些属性出现的时候,表示该元素创建了一个BFC。
4.2 BFC的作用
1、消除浮动元素对非非浮动元素的影响
2、清除内部浮动
3、防止垂直 margin 重叠。
相邻块盒子的垂直外边距折叠只有他们是在同一BFC时才会发生。如果他们属于不同的BFC,他们之间的外边距将不会折叠
5.编码实战
1、消除浮动元素对非非浮动元素的影响,看下面的例子,没有创建BFC的情况
main{
/*position:absolute;*/
/*display: inline-block;*/
/*display: table;*/
/*display: flex;*/
/*overflow: hidden;*/
width:1000px;
margin:0auto;
background-color:gainsboro;
border:solid1px;
}
.left{
float:left;
/*margin: 50px 0;*/
width:200px;
height:200px;
background-color:rgba(86,251,166,.5);
}
.right{
/*overflow: hidden;*/
/*float: left;*/
/*margin: 50px 0;*/
width:500px;
background-color:#fff965;
}
.collapse{
/*overflow: hidden;*/
}
我是测试文字我是测试文字我是测试文字我是测试文字我是测试文字我是测试文字我是测试文字我是测试文字
我是测试文字我是测试文字我是测试文字我是测试文字我是测试文字我是测试文字我是测试文字我是测试文字
我们看到浮动盒子覆盖在非浮动盒子上,父元素高度塌陷(没有包围浮动元素)。如果给父元素一个overflow:hidden(创建BFC),看看什么情况
main{
/*position:absolute;*/
/*display: inline-block;*/
/*display: table;*/
/*display: flex;*/
overflow:hidden;
width:1000px;
margin:0auto;
background-color:gainsboro;
border:solid1px;
}
父元素将浮动元素包裹起来了,恢复了高度。
2、我们再给右边盒子创建BFC ,看看是什么情况
.right{
overflow:hidden;
/*float: left;*/
/*margin: 50px 0;*/
width:500px;
background-color:#fff965;
}
3、BFC防止垂直 margin 重叠的作用。
没有BFC的情况下两个元素的上下外边距是折叠的,值取最大的一个。看下面例子:
.left{
/*float: left;*/
margin:50px0;
width:200px;
height:100px;
background-color:rgba(86,251,166,.5);
}
.right{
overflow:hidden;
/*float: left;*/
margin:50px0;
width:500px;
background-color:yellow;
}
我是测试文字我是测试文字我是测试文字我是测试文字我是测试文字我是测试文字我是测试文字我是测试文字
我是测试文字我是测试文字我是测试文字我是测试文字我是测试文字我是测试文字我是测试文字我是测试文字
我们看到类为right的元素也触发了BFC(overflow:hidden;)但是没有消除两个元素的外边距折叠。我们在回顾一下BFC的特性:处于BFC内部的元素与外部的元素相互隔离,使内外元素的定位不会相互影响。也就是BFC用于消除内部元素与外部元素的相互影响。处于同级的BFC就没有这个特性。如果在类为right元素外部包裹一个BFC元素,给类为collapse 的盒子一个overflow:hidden(创建BFC),看看什么情况
我是测试文字我是测试文字我是测试文字我是测试文字我是测试文字我是测试文字我是测试文字我是测试文字
我是测试文字我是测试文字我是测试文字我是测试文字我是测试文字我是测试文字我是测试文字我是测试文字
.collapse{
overflow:hidden;
}
现在另个盒子外边距分离了。
总结一下
元素创建BFC后有如下的效果
1、消除浮动元素对非非浮动元素的影响
2、清除内部浮动
3、防止垂直 margin 重叠。
6.扩展思考
不同条件触发BFC产生的效果是否一样?
display:flex,属性创建的BFC会让内部子元素也继承BFC,其他条件是一样的效果。
7.参考文献
参考1:http://www.cnblogs.com/lhb25/p/inside-block-formatting-ontext.html
参考2:http://web.jobbole.com/84808
参考3:http://www.cnblogs.com/elcarim5efil/p/4745796.html
参考4:http://www.cnblogs.com/lhb25/p/inside-block-formatting-ontext.html