什么是BFC
BFC,英语全称 Block formatting contexts,翻译成中文就是“块级格式化上下文”。
简单来说,就是页面中的一块渲染区域,并且有一套自己的渲染规则。它决定了元素如何对其内容进行布局,以及与其他元素的关系和相互作用。当涉及到可视化布局的时候,BFC提供了一个环境,HTML元素在这个环境中按照一定规则进行布局。
言简意赅的说,BFC是一个独立的布局环境,BFC内部的元素布局与外部互不影响。
BFC 的布局规则有如下几条:
- 内部的 Box 会在垂直方向一个接着一个地放置。
- Box 垂直方向上的距离由 margin 决定。属于同一个 BFC 的两个相邻的 Box 的 margin 会发生重叠。
- 每个盒子的左外边框紧挨着包含块的左边框,即使浮动元素也是如此。
- BFC 的区域不会与浮动 Box 重叠。
- BFC 就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之亦然。
- 计算 BFC 的高度时,浮动子元素也参与计算。
实际上在一个标准流中 body 元素就是一个天然的 BFC。
其他区域,单独设置成一个 BFC,这里记录了一些常见的方式:
元素或属性 | 属性值 |
---|---|
根元素 | |
float | left、right |
postion | absolute、fixed |
overflow | auto、scroll、hidden |
display | inline-block、table-cell |
上面只记录了一些常见的方式,完整的 BFC 触发方式可以参阅:https://developer.mozilla.org/zh-CN/docs/Web/Guide/CSS/Block_formatting_context
那么块级格式化上下文有啥具体的用处呢?我们来看几个场景
常见的 BFC 应用有:
- 解决浮动元素令父元素高度坍塌的问题
- 解决非浮动元素被浮动元素覆盖问题
- 解决外边距垂直方向重合的问题
- 解决浮动元素令父元素高度坍塌的问题
<div class="father"> <div class="son"></div> </div>
复制
.father{ border: 5px solid; } .son{ width: 100px; height: 100px; background-color: blue; float: left; }
复制
在上面的代码中,父元素的高度是靠子元素撑起来的,但是一旦我们给子元素设置了浮动,那么父元素的高度就塌陷了。如下:
此时我们就可以将父元素设置成一个 BFC,例如:
.father{ border: 5px solid; overflow: hidden; /* 将父元素设置为一个 BFC */ } .son{ width: 100px; height: 100px; background-color: blue; float: left; }
复制
效果:可以看到由于父元素变成 BFC,高度并没有产生塌陷了,其原因是在计算 BFC 的高度时,浮动子元素也参与计算
- 非浮动元素被浮动元素覆盖
<div class="box1"></div> <div class="box2"></div>
复制
.box1{ width: 100px; height: 50px; background-color: red; float: left; } .box2{ width: 50px; height: 50px; background-color: blue; }
复制
在上面的代码中,由于 box1 设置了浮动效果,所以会脱离标准流,自然而然 box2 会往上面跑,结果就被高度和自己一样的 box1 给挡住了。
设置 box2 为 BFC,如下:
.box1{ width: 100px; height: 50px; background-color: red; float: left; } .box2{ width: 50px; height: 50px; background-color: blue; overflow: hidden; }
复制
效果:由于 BFC 的区域不会与浮动 box 重叠,所以即使 box1 因为浮动脱离了标准流,box2 也不会被 box1 遮挡
基于此特点,我们就可以制作两栏自适应布局,方法就是给固定栏设置固定宽度,给不固定栏开启 BFC。
<div class="left">导航栏</div> <div class="right">这是右侧</div>
复制
*{ margin: 0; padding: 0; } .left { width: 200px; height: 100vh; background-color: skyblue; float: left; } .right { width: calc(100% - 200px); height: 100vh; background-color: yellowgreen; }
复制
效果:在上面的代码中,我们要设置两栏布局,左边栏宽度固定,右边栏自适应。结果我们发现右侧出现了空白
究其原因就是右侧区域与浮动盒子重叠了
修改 .right 部分的代码,添加 overflow:hidden 使其成为一个 BFC:
.right { width: calc(100% - 200px); height: 100vh; background-color: yellowgreen; overflow: hidden; }
复制
效果:因为 BFC 的区域不会与浮动 Box 重叠,所以右侧空白没有了
- 外边距垂直方向重合的问题
BFC 还能够解决 margin 折叠的问题,例如:
<div class="box1"></div> <div class="box2"></div>
复制
* { margin: 0; padding: 0; } .box1{ width: 100px; height: 100px; background-color: red; margin-bottom: 10px; } .box2{ width: 100px; height: 100px; background-color: blue; margin-top: 10px; }
复制
效果:
此时我们可以在 box2 外部再包含一个 div,并且将这个 div 设置为 BFC,如下:
<div class="box1"></div> <div class="container"> <div class="box2"></div> </div>
复制
* { margin: 0; padding: 0; } .box1{ width: 100px; height: 100px; background-color: red; margin-bottom: 10px; } .box2{ width: 100px; height: 100px; background-color: blue; margin-top: 10px; } .container{ overflow: hidden; }
复制
效果:
更多关于格式化上下文的内容,可以参阅 MDN:
BFC:https://developer.mozilla.org/zh-CN/docs/Web/Guide/CSS/Block_formatting_context