什么是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 应用有:
- 解决浮动元素令父元素高度坍塌的问题
- 解决非浮动元素被浮动元素覆盖问题
- 解决外边距垂直方向重合的问题
- 解决浮动元素令父元素高度坍塌的问题
html
<div class="father">
<div class="son"></div>
</div>
css
.father{
border: 5px solid;
}
.son{
width: 100px;
height: 100px;
background-color: blue;
float: left;
}
在上面的代码中,父元素的高度是靠子元素撑起来的,但是一旦我们给子元素设置了浮动,那么父元素的高度就塌陷了。如下:
此时我们就可以将父元素设置成一个 BFC,例如:
css
.father{
border: 5px solid;
overflow: hidden;
/* 将父元素设置为一个 BFC */
}
.son{
width: 100px;
height: 100px;
background-color: blue;
float: left;
}
效果:可以看到由于父元素变成 BFC ,高度并没有产生塌陷了,其原因是在计算 BFC 的高度时,浮动子元素也参与计算
- 非浮动元素被浮动元素覆盖
html
<div class="box1"></div>
<div class="box2"></div>
css
.box1{
width: 100px;
height: 50px;
background-color: red;
float: left;
}
.box2{
width: 50px;
height: 50px;
background-color: blue;
}
在上面的代码中,由于 box1 设置了浮动效果,所以会脱离标准流,自然而然 box2 会往上面跑,结果就被高度和自己一样的 box1 给挡住了。
设置 box2 为 BFC,如下:
css
.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。
html
<div class="left">导航栏</div>
<div class="right">这是右侧</div>
css
*{
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:
css
.right {
width: calc(100% - 200px);
height: 100vh;
background-color: yellowgreen;
overflow: hidden;
}
效果:因为 BFC 的区域不会与浮动 Box 重叠,所以右侧空白没有了
- 外边距垂直方向重合的问题
BFC 还能够解决 margin 折叠的问题,例如:
html
<div class="box1"></div>
<div class="box2"></div>
css
* {
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,如下:
html
<div class="box1"></div>
<div class="container">
<div class="box2"></div>
</div>
css
* {
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