BFC
BFC 全称 Block Formatting Context,即块级格式化上下文。
每个渲染区域用formatting context表示,它决定了其子元素将如何定位,以及和其他元素的关系和相互作用
在正常流中的盒子要么属于块级格式化上下文,要么属于内联格式化上下文
BFC特性&创建条件
特性
内部的Box会在垂直方向,从顶部开始一个接一个地放置。
Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生叠加
每个元素的margin box的左边,与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
BFC的区域不会与float box叠加。
BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之亦然。
计算BFC的高度时,浮动元素也参与计算。
——《CSS之BFC详解 》
创建条件
块格式化上下文由以下之一创建:
根元素或其它包含它的元素
浮动 (元素的
float
不是none
)绝对定位的元素 (元素具有
position
为absolute
或fixed
)内联块
inline-blocks
(元素具有display: inline-block
)表格单元格 (元素具有
display: table-cell
,HTML表格单元格默认属性)表格标题 (元素具有
display: table->caption
, HTML表格标题默认属性)块元素具有
overflow
,且值不是visible
display:flow-root
BFC 可以用来做什么?
1. 解决margin重叠的问题
根据BFC的特性,同一个BFC下的两个相邻的盒子会出现垂直margin重叠的问题,这个问题会影响我们对页面布局的控制,通常我们可以为其中一个盒子添加一个父元素,并使其触发BFC,即可解决这个问题:
解决margin重叠的问题
2. 浮动带来的布局问题
根据前面其他作者总结的BFC特性的第三条和第四条,我们知道在同一个BFC下即使有元素浮动,BFC下元素的最左边边缘总是会与包含它的盒子左边相接触,那么就会出现浮动元素遮盖了其他元素的情况。BFC还有一条重要特性:BFC的区域不会与float box 重叠。试想,在一个BFC,如果存在一个float元素,和一个div,浮动元素会遮盖住div,此时,如果给这个div构建一个新的BFC,由于BFC特性,内外不相互影响,此时div会被float元素挤开。
比如下面这个例子,绿色盒子会因为浮动遮盖住红色的盒子,但由于两个盒子都在同一个BFC(body元素)下,根据BFC特性,红色盒子会与包含块相接,此时只要让红色盒子触发BFC,我们为红色盒子添加一个触发BFC的条件overflow:hidden,此时红色盒子由于BFC的特性隔离开绿色,这样我们就可以通过float元素的方式实现两栏布局。
浮动带来的布局问题
3. 清除浮动
这里就要说到我们常见的浮动元素引起的高度坍塌的问题。由于浮动特性,浮动元素会脱离父元素,我们是否可以通过触发BFC来解决高度坍塌的问题呢?
根据特性的第6条,在触发BFC后,这个盒子的高度将包含浮动元素的高度,在计算时,浮动元素会参与高度计算,我们可以理解为,当一个父元素中包含了浮动元素,而浮动元素超出了父元素,此时我们为父元素创建BFC,那么浮动元素就会包裹进这个BFC解决了父元素中高度塌陷的问题。
如下面的例子,div.parent
包含了两个div.child
,而两个div由于赋予了float:left
使其浮动,导致了div.parent
高度的坍塌,此时我们给div.parent
添加一个overflow:hidden
属性值,使div.parent
触发BFC,由于BFC下的盒子会包含浮动元素的高度,因此盒子就被撑了起来,高度塌陷的问题也就得到了解决。
清除浮动
关于边距合并
CSS之BFC详解 中讲解的三个案例和上面讲解的这三种情况都是关于边距合并的方法。
但使用overflow:hidden
或者其他方式或多或少会带来一些副作用和潜在的问题,可能在页面刚开始创建的时候这些问题不会完全显现,但是埋下祸根...
一般我们在构造页面的时候就尽量不用这些方式。
举个例子,对于margin
重叠的问题,我们使用margin-top
就可以很好的解决。
参考:
作者:evenyao
链接:https://www.jianshu.com/p/4dafbc35d998