一、何为BFC
块级格式化上下文(Block Formatting Context)是网页CSS视觉渲染的一部分,并用于决定盒子的布局。在定位体系中属于常规流(Normal Flow)(另外两种定位体系为浮动(Floats)和绝对定位(Absolute Positioning))。
二、BFC如何形成
BFC的形成,根据W3C所言:
浮动、绝对定位元素(
position
为absolute
或fixed
)、行内块元素display:inline-block
、表格单元格display:table-cell
、表格标题display:table-caption
以及overflow
属性值不为visible
的元素(除了该值被传播到视点viewport
的情况)将创建一个新的块级格式化上下文。
通俗理解的话,一个BFC元素至少满足一下条件中的一个:
1.float的值不为none
2.position的值不为static或relative
3.display的值为table-cell、table-caption、inline-block、flex或inline-flex
4.overflow的值不为visiable
满足以上条件的元素将有BFC元素的一些特性,理解并掌握这些特性可以让你在CSS布局中更加得心应手,也可以从根源上理解一些常见代码实现效果的原理,如清除浮动,自适应布局等。
三、BFC有什么特性
1.BFC中盒子对齐
W3C规范中写到:
在BFC上下文中,每个盒子的左外侧紧贴包含块的左侧(从右到左的格式里,则为盒子右外侧紧贴包含块右侧),甚至有浮动也是如此(尽管盒子里的行盒子
Line Box
可能由于浮动而变窄),除非盒子创建了一个新的BFC(在这种情况下盒子本身可能由于浮动而变窄)。
如图所示,所有BFC的盒子都会遵循左对齐的的对齐方式。
2.关于外边距折叠
大家应该知道,标准文档流的同胞元素在竖直方向上会发生外边距折叠的现象,如下图
A的下边距为100px,B的上边距为50px,发生外边距折叠后A、B竖直间距为50xp。(更多外边距折叠问题后面会有博客专题)
一个BFC盒子与它的子元素之间不会发生外边距折叠。但是同一个BFC盒子内部的子元素之间也是会发生外边距折叠的,如下图:
可如果为其中一个子元素创建一个新的BFC(不同于父元素那个BFC盒子),让这些子元素分属于不同的BFC,他们之间就不会发生外边距折叠了,如下图:
HTML为:
<div class="container"> <p>Sibling 1</p> <p>Sibling 2</p> <div class="newBFC"> <p>Sibling 3</p> </div> </div>
CSS为:
.container { background-color: red; overflow: hidden; /* creates a block formatting context */ } p { margin: 10px 0; background-color: lightgreen; } .newBFC { overflow: hidden; /* creates new block formatting context */ }
3.BFC内外元素互不影响
这条通俗来讲就是:无论BFC内部元素如何布局——浮动、绝对定位或是其他,都不会对BFC盒子外的其他盒子的布局造成影响,同时,外部元素也不会影响BFC内部元素的布局。这个特性用途很广,也解释了为何BFC可以清除浮动了。
四、如何应用BFC
BFC的特性是很多CSS规范背后的原理,掌握这些特性,反过来应用它们就可以实现很多效果:
一、使用BFC避免外边距折叠
BFC特性2中的实例就实现了这个特性的反向应用。
二、使用BFC清除浮动
由于特性3,我们只需要用BFC包含浮动块就可以达到清除浮动影响的效果,也就是让包含浮动的父元素BFC化,这就是好几种清除浮动方法的根本原理:
1.设置父元素也浮动;
2.设置父元素的display为table(不常用);
3.设置父元素overflow:hidden/auto;
都是让父元素BFC化,来清除对BFC外元素的影响。(下一篇博客将总结各种清除浮动的方法)
三、使用BFC避免文字环绕效果
大部分时候我们并不需要浮动带来的文字环绕效果(这个现象是由于特性1,详细解释可参考http://web.jobbole.com/83149/),用BFC来清除这个效果是个不错的选择。如下图:
我们将文字部分的包含块设置overflow:hidden就可以实现清除文环绕了。
四、多列布局与自适应布局
多列布局:
如果我们创建一个占满整个容器宽度的多列布局,在某些浏览器中最后一列有时候会掉到下一行。这可能是因为浏览器四舍五入了列宽从而所有列的总宽度会超出容器。但如果我们在多列布局中的最后一列里创建一个新的BFC,它将总是占据其他列先占位完毕后剩下的空间。(对于多列布局这不一定是个好办法,在实际应用中更推荐使用弹性盒子或者用最后一个盒子margin负值来解决。)
自适应布局:
类似应用三的例子中,如果设置右边浮动元素margin-right(或左边BFC元素margin-left)为一定值,就实现了左右两列的自适应布局,无论左右两部分width怎么变化,都可以保持很好的布局状况而不会乱掉,这种情况下BFC的设置方法可以是:
1.overflow:auto/hidden; IE7+
2.display:inline-block; IE6/IE7
3.display:table-cell; IE8+
五、最后
本文参考了好几篇博文,原文中关于用法或原理有更详尽的解释,下面贴出地址:
张鑫旭 CSS深入理解流体特性和BFC特性下多栏自适应布局
http://www.zhangxinxu.com/wordpress/2015/02/css-deep-understand-flow-bfc-column-two-auto-layout/
理解CSS中的块级格式化上下文
还是那句话,感谢前人栽阴!