什么是BFC?
BFC(Block Formatting Context),即块级格式化上下文,MDN上的解释为是 Web 页面的可视 CSS 渲染的一部分,是块级盒子的布局过程发生的区域,也是浮动元素与其他元素交互的区域。
首先什么是格式化上下文?在HTML文档中,块级元素独占一行,从上往下排列,行内元素由内容撑开,从左往右依次排列,这种浏览器默认的排列方式我们可以称为文档流(normal flow)。
在文档流中,浏览器为这两套排列规则创建不同的区域,让它们各自在自己的区域生效,CSS中这种有特定规则的区域就叫格式化上下文,而负责块级盒子上下排列的区域就叫块级格式化上下文BFC(Block Formatting Context),负责行内盒子水平排列的就叫行内格式化上下文IFC(Inline Formatting Context)。文档流就是通过BFC和IFC的协同工作来实现布局的,因此文档流也叫Block-and-Inline Layout。

当然,还有其它类型的上下文,例如flex布局中的FFC(Flex Formatting Context)...
display:block;完整写法为display:block flow;---对外为块级盒子,对内按照文档流的方式排列
display:flex;完整写法为display:block flex;---对外为块级盒子,对内子元素按flex布局排列
总之,BFC是一个独立的渲染区域,内部元素以块级盒子的规则进行垂直排列 ,区域内部的布局不会影响外部元素,也不会被外部元素影响。
BFC不等同于只有块级盒子参与,如果是行内元素(如span或纯文本),渲染引擎会通过建立 IFC(纯行内环境)或生成匿名块级盒子并在其内部建立 IFC(混合环境)的方式,将行内元素的排版工作下放。
在CSS规范中,同一个BFC中,当块级盒子的垂直外边距直接接触时,这两个外边距就会折叠成,也就是margin外边距折叠。比如这个例子,body和两个div都处于同一个BFC(ps:html根标签会创建页面的第一个BFC)中,就发生了父子与兄弟元素的外边距折叠问题。
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<title>margin塌陷</title>
<style>
.a {
height: 60px;
margin-bottom: 40px;
margin-top: 40px;
background: #8ccfff;
}
.b {
height: 60px;
margin-top: 20px;
background: #ffc98a;
}
</style>
</head>
<body>
<div class="a"></div>
<div class="b"></div>
</body>
</html>
因此 ,只需要让这几个块级盒子不再处于同一个BFC即可解决问题,那么什么情况下会创建新的BFC呢?
创建BFC
常见的创建BFC的条件如下:
- html根标签
- display: flow-root
完整写法为display: block flow-root(外部以block的形式显示。内部显示类型为flow-root,唯一作用是创建一个新的BFC,没有任何副作用,因此是比较推荐的写法)
- felx/grid容器的直接子元素
- float 值不为none
- overflow值不为visible、clip如 (hidden、auto、scroll)
.....
BFC不仅仅能阻止外边距折叠问题。
- 元素开启BFC 后,自己不会被其他浮动元素所覆盖
- 元素开启BFC 后,子元素浮动时自身高度不会塌陷

Comments NOTHING