1. 什么是FC,什么是BFC
-
FC 的全称是Formatting Context(格式化上下文),元素在标准流里面都是属于一个FC的:
-
块级元素的布局属于Block Formatting Context(BFC)
- 也就是block level box都是在BFC中布局的
-
行内级元素的布局属于Inline Formatting Context(IFC)
- 而inline level box都是在IFC中布局的
2. 那么在什么情况下会创建BFC呢
- 根元素()
- 浮动元素(元素的 float 不是 none)
- 绝对定位元素(元素的 position 为 absolute 或 fixed)
- 行内块元素(元素的 display 为 inline-block)
- display 值为 flow-root 的元素
- 表格单元格(元素的 display 为 table-cell,HTML表格单元格默认为该值),表格标题(元素的 display 为 table-caption,HTML表格标题默认为该值)
- 匿名表格单元格元素(元素的 display 为 table、table-row、table-row-group、table-header-group、table-footer-group(分别是HTML table、row、tbody、thead、tfoot的默认属性)或 inline-table)
- overflow 计算值(Computed)不为 visible 的块级元素
- 弹性元素(display 为 flex 或 inline-flex 元素的直接子元素)
- 网格元素(display 为 grid 或 inline-grid 元素的直接子元素)
3. BFC有什么作用呢
官方对BFC作用的描述:
- 在块格式上下文中,盒子从包含块的顶部开始,一个接一个地垂直排列。两个相邻框之间的垂直距离由“margin”属性决定。块格式上下文折叠中相邻块级框之间的垂直边距。
- 在块格式上下文中,每个框的左外缘与包含块的左边缘相连(对于从右到左的格式,是右边缘相连)。即使存在浮动(尽管一个盒子的行盒可能会因为浮动而收缩),除非盒子建立了一个新的块格式化上下文(在这种情况下,盒子本身可能会因为浮动而变窄)。
简单概述为:
- 在BFC中,box会在垂直方向上一个挨着一个的排布
- 垂直方向的间距由margin属性决定
- 在同一个BFC中,相邻两个box之间的margin会折叠(collapse)
- 在BFC中,每个元素的左边缘是紧挨着包含块的左边缘的
4. 我们来看两个问题
问题一:为什么box1和box2各设置了margin为100px,为什么实际的margin-top之间只有100px
问题二:由问题一我们可以看到正常情况下,box的高度也是可以显示的,因为设置了400px,但是为什么设置了浮动之后box的高度就塌陷了呢
5. 那么BFC的作用就很明显了
- 解决margin的折叠问题
- 解决浮动高度塌陷问题
6. BFC是怎样解决折叠问题的
- 在同一个BFC中,相邻两个box之间的 margin 会折叠(collapse)
- 那么如果我们让两个box是不同的BFC呢?那么就可以解决折叠问题。
7. 解决浮动高度塌陷的方案
-
网上有很多说法,BFC可以解决浮动高度塌陷,可以实现清除浮动的效果。
- 但是从来没有给过BFC可以解决高度塌陷的原理或者权威的文档说明;
- 他们也压根没有办法解释,为什么可以解决浮动高度的塌陷问题,但是不能解决绝对定位元素的高度塌陷问题呢?
-
事实上,BFC解决高度塌陷需要满足两个条件:
- 浮动元素的父元素触发BFC,形成独立的块级格式化上下文(Block Formatting Context);
- 浮动元素的父元素的高度是auto的;
-
BFC的高度是auto的情况下,是如下方法计算高度的
- 如果只有inline-level,是行高的顶部和底部的距离;
- 如果有block-level,是由最底层的块上边缘和最底层块盒子的下边缘之间的距离
- 如果有绝对定位元素,将被忽略;
- 如果有浮动元素,那么会增加高度以包含这些浮动元素的下边缘。