BFC全称是block formatting context,中文为“块状格式化上下文”。单看这个名字,完全不知道BFC到底是个什么东西。
在MDN上,BFC的定义为:是Web页面可视化CSS渲染的一部分,是块盒子的布局过程发生的区域,也是浮动元素与其它元素交互的区域。
……
好像还是看不懂…
简单的来说,BFC是一种特性,将容器隔离,容器里的元素不会在布局上影响到外面的元素,并且有一些普通元素没有的特性。
下面就看看BFC到底和普通元素有什么不同。
BFC与margin合并
margin合并
块级元素的上外边距或下外边距有时会合并为单个边距,这样的现象称为“margin合并”。
从上述定义中可以得到两点信息:
- 块级元素,但不包括浮动和绝对定位元素,尽管浮动和绝对定位可以让元素块状化。
- 只发生在垂直方向(在不考虑
writing-mode
的情况下)。严格来讲,是只发生在当前文档流方向相垂直的方向上,默认文档流是水平流,因此发生margin合并的就是垂直方向。
margin合并的3种场景
1 相邻兄弟元素margin合并。
1 | p { margin: 20px 0; } |
第一行和第二行之间的间距还是20px,而不是40px,因为第一行的margin-bottom
和第二行的margin-top
合并在一起了。
2 父级和第一个/最后一个子元素
1 | <div> |
这3种设置是等效的,都表现为父元素距离上方80px。在实际开发的时候,给我们带来麻烦的多半是这里的父子margin合并。
其中之一的解决margin合并的方法就是把父元素设置为块状格式化上下文(BFC)元素。
为什么BFC可以解决margin合并
因为 BFC容器里的元素不会在布局上影响到外面的元素。
在父子margin合并时,将父元素设置为BFC元素,父元素和子元素就不在同一个BFC中了,所以父元素内的元素的布局不会影响到父元素外。
在兄弟元素margin合并时,我们给其中一个元素添加一个BFC父级元素,使两个曾经的兄弟元素不在同一个BFC下,同样不会互相影响。
BFC与float
float
浮动的设计目的是为了实现文字环绕效果,主要是文字环绕图片的显示效果。
float的特性:
- 包裹性
- 块状并格式化上下文
- 破坏文档流
- 没有任何margin合并
float父元素高度塌陷
float会破坏文档流,使父元素的高度塌陷,与外面的元素接触,实现环绕效果。
在如今,float很少发挥其原本的作用,而是大量用来布局,所以高度塌陷反而成了不需要的特性。
BFC元素在计算高度时会包括浮动元素。
所以将父元素触发BFC可以解决高度塌陷的问题。
清除浮动
触发BFC,就无须使用clear:both
属性清除浮动的影响了。因为具有BFC特性的元素的子元素不会受外部元素的影响。
想要彻底清除浮动的影响,最适合的属性不是clear而是overflow,一般使用overflow:hidden
,利用BFC特性彻底解决浮动对外部或兄弟元素的影响。
BFC的特性
综上所述,BFC大概有以下特性
- BFC容器里的元素不会在布局上影响到外面的元素。
- BFC元素在计算高度时会包括浮动元素。
- BFC元素不会与浮动元素重叠。
触发BFC的条件
<html>
根元素- float的值不为none
- overflow的值为auto、scroll或hidden
- display的值为table-cell、table-caption或inline-block
- position的值不为relative和static