1. FC – Formatting Context
FC的全称是Formatting Context,元素在标准流里面都是属于一个FC的;
块级元素的布局属于Block Formatting Context(BFC)
也就是block level box都是在BFC中布局的;
行内级元素的布局属于Inline Formatting Context(IFC)
inline level box都是在IFC中布局的;
MDN上有整理出在哪些具体的情况下会创建BFC:
- 根元素(<html>)
- 浮动元素(元素的 float 不是 none)
- 绝对定位元素(元素的 position 为 absolute 或 fixed)
- 行内块元素(元素的 display 为 inline-block)
- 表格单元格(元素的 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 元素的直接子元素)
- display 值为 flow-root 的元素
2. BFC的作用
官方文档对BFC作用的描述:
简单的概括
- 在BFC中,box会在垂直方向上一个挨着一个的排布;
- 垂直方向的间距由margin属性决定;
- 在同一个BFC中,相邻两个box之间的margin会折叠(collapse);
- 在BFC中,每个元素的左边缘是紧挨着包含块的左边缘的;
解决的问题
- 解决margin的折叠问题;
- 解决浮动高度塌陷问题;
3. 解决兄弟div上下margin折叠问题
在同一个BFC中,相邻两个box之间的margin会折叠(collapse)
上面的文档截图中已经指出会产生折叠问题
The vertical distance between two sibling boxes is determined by the 'margin' properties. Vertical margins between adjacent block-level boxes in a block formatting context collapse.
因为同属于html这个大的BFC盒子中, 可以理解成同属于一个作用域,该作用域的特性就是会折叠。那么我们要是将其中一个div包含于某个元素,再将这个父元素触发BFC机制,那么原本相邻的div就会属于不同的BFC作用域就不会产生margin折叠的问题。
加入包含块未触发父元素BFC机制
触发包含块BFC机制,这里选择 overflow 计算值(Computed)不为 visible 的块元素 该条触发模式
虽然说平常都在使用,了解了本质才会使理解更加清晰。
4. 解决内部只有浮动元素高度塌陷问题
网上有很多说法,BFC可以解决浮动高度塌陷,可以实现清除浮动的效果。
为什么可以解决浮动高度的塌陷问题,但是不能解决绝对定位元素的高度塌陷问题呢?
明明两者都是脱标。又有什么不一样呢?
BFC解决高度塌陷需要满足两个条件:
- 浮动元素的父元素触发BFC机制;
- 浮动元素的父元素的高度是auto的;(height不设置默认就是auto)
BFC的高度是auto的情况下,是如下方法计算高度的
官方文档:
- 如果只有inline-level,是行高的顶部和底部的距离;
- 如果有block-level,是由最底层的块上边缘和最底层
块盒子的下边缘之间的距离 - 如果有绝对定位元素,将被忽略;
- 如果有浮动元素,那么会增加高度以包括这些浮动元素的下边缘
看了文档就很清楚就知道刚刚问题的原因了,规定如此