简介
我们常说的文档流其实分为定位流、浮动流和普通流三种。而普通流其实就是指BFC中的FC。
FC是formatting context的首字母缩写,直译过来是格式化上下文,它是页面中的一块渲染区域,有一套渲染规则,决定了其子元素如何布局,以及和其他元素之间的关系和作用。
常见的FC有BFC、IFC(行级格式化上下文),还有GFC(网格布局格式化上下文)和FFC(自适应格式化上下文),这里就不再展开了。
BFC是什么?
BFC
全称:Block Formatting Context,BFC
翻译过来就是块级格式化上下文。
有人又要问了,那块级格式化上下文又是什么呢?
BFC是Web页面的可视化CSS渲染的一部分,是块盒子的布局过程发生的区域,也是浮动元素与其他元素交互的区域。
说白了,他就是一个规则。
BFC的规则是什么呢?
- 内部的Box会在垂直方向,一个接一个地放置。属于同一个BFC的两个相邻Box的margin会发生重叠
- 每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
- BFC的区域不会与float box重叠。(清除浮动)
- BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。(解决margin塌陷)
- 计算BFC的高度时,浮动元素也参与计算(解决父级高度塌陷)
什么叫同一个BFC?
BFC包含创建该上下文元素的所有子元素,但不包括创建了新BFC的子元素的内部元素。
1 <div id='div_1' class='BFC'> 2 <div id='div_2'> 3 <div id='div_3'>div> 4 <div id='div_4'>div> 5 div> 6 <div id='div_5' class='BFC'> 7 <div id='div_6'>div> 8 <div id='div_7'>div> 9 div> 10 div>
根据定义,#div_1创建了一个块格式上下文,这个上下文包括了#div_2
、#div_3
、#div_4
、#div_5
。由于#div_5
创建了新的BFC,所以#div_6
和#div_7
就被排除在外层的BFC之外。
什么情况下触发BFC?
- 根元素(
)
- float不为
none
- position为
fixed/absolute
- overflow不为
visible
- 行内元素:
display:inline-block
- 表格元素
display:table-cell(表格单元)/table-caption(表格标题)/table-cell/table/table-row/ table-row-group/table-header-group/table-footer-group
- 弹性元素(display为 flex 或 inline-flex元素的直接子元素)
- 网格元素(display为 grid 或 inline-grid 元素的直接子元素)
BFC的应用
应用一:解决父子margin塌陷
1 <div class="parent"> 2 <div class="child">div> 3 div>
1 .parent { 2 width: 200px; 3 height: 200px; 4 background-color: lightcoral; 5 margin-top: 20px; 6 } 7 8 .child { 9 width: 100px; 10 height: 100px; 11 background-color: lightseagreen; 12 margin-top: 40px; 13 }
我们这样写了之后发现父亲跟着儿子走了,效果图如下
这时候我们触发父级BFC(具体触发方法前面是有的)。
在这里重点说一下为啥就解决了?
BFC的规则里说道,处于同一个BFC的两个相邻盒子才会发生margin重叠。打破这个规则那就解决了。可是可能有人疑问,明明父亲还包着儿子,这就不是同一个BFC了吗?具体请看什么叫同一个BFC
其实这里父亲和儿子是不在同一BFC哒
垂直摆放的两个兄弟盒子,上面设置margin-bottom下面设置margin-top,这时候也会发生margin重叠,这时候我们选择只设置一个。
补充一点
margin重叠计算规则
- 同正取大
- 同负取小
- 一正一负取加和值
应用二:浮动模型
当盒子设置float:left/right就变成浮动元素。这些元素站队边界是父级边界。
1 .father{ 2 border: 5px solid black; 3 width: 300px; 4 } 5 .son1{ 6 border: 5px solid #f66; 7 width: 100px; 8 height: 100px; 9 float: left; 10 11 } 12 .son2{ 13 border: 5px solid #f66; 14 width:100px; 15 height: 100px; 16 float: left; 17 }
原因: 浮动元素产生浮动流,所有产生浮动流的元素,块级元素看不到它们,但产生了bfc的元素和文本元素类属性(inline)以及文本都能看到浮动元素。 解决方案:
- 清除浮动流
最后一个子元素添加
1 p{ 2 clear:both; 3 }
伪元素清除浮动:
1 .father::after { 2 content: ''; 3 display: block; 4 clear: both; 5 }
解释一下为什么要用display:block?
clear 很特殊,想让他生效,必须是块级元素才可以,而::after 是行级元素
- 触发父级BFC 内部把元素转换成inline-block,让父级元素可以“看到”浮动元素,从而解决问题。实际上是应用到布局规则中的最后一条特性:计算BFC的高度时,浮动元素也参与计算。