可能对于很多前端而言,BFC 都是神秘的存在。大多数人停留在只知其一,不知其二的状态。本文就来揭秘一下 CSS 中的 BFC。其实你不需要去纠结它的定义。你只需要知道 BFC 是一个独立的渲染区域,清楚它的布局规则及应用即可。
何为 BFC
BFC 即 Block Formatting Context。中文译为块级格式化上下文。在介绍 BFC 之前,你需要先了解 Box 的概念。Box 是 CSS 布局的对象和基本单位。一个页面是由若干个 Box 组成。元素的类型和 display
属性决定了 Box 如何布局。
Formatting Context 是 W3C 中 CSS2.1 规范中的一个概念。它是页面的一块渲染区域。并且有一套自己的渲染规则。它决定了元素如何定位以及与其他元素之间的作用关系。
最常见的 Formatting Context 有 Block Fomatting Context (简称 BFC)和 Inline Formatting Context (简称 IFC)。
BFC 布局规则
- Box 盒子依次垂直排列。
- Box 盒子之间的距离由
margin
属性决定。属于同一个 BFC 的两个相邻盒子的margin
值会发生重叠。 - Box 盒子(块盒与行盒)margin 值为 0 的情况下其左边与块级元素左边重叠。
- BFC 的区域不会与 float 区域重叠。
- BFC 就是页面上一个独立的容器。容器里面的元素不会影响到外面的元素。反之如此。
- 计算 BFC 高度时,浮动元素也参与计算。
创建 BFC
- 根元素或者包含它的元素
- 浮动元素(float 属性不为 none)
- position 为 absolute 或者 fixed
- overflow 不为 visible 的块元素
- display 为 inline-block(内联块),table-cell(表格单元格),table-cation(表格标题),table-row,flex,inline-flex,flow-root(弹性布局)
BFC 的应用
- 防止 margin 重叠(同一个 BFC 的两个相邻 Box 的
margin
会发生重叠。触发生成两个 BFC,就不会发生重叠)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<style>
div {
color: #fff;
background: pink;
width: 200px;
line-height: 100px;
text-align:center;
margin: 20px;
}
</style>
<body>
<div>盒子1</div>
<div>盒子2</div>
</body>
</html>
以上 盒子1 和 盒子2 之间垂直距离重叠了一个 20px 的 margin 值。将其中一个 Box 触发 BFC(设置 display 为 inline-block 即可)就不会重叠。
- 清除浮动(创建一个新的 BFC,计算 BFC 高度时,浮动元素也会计算在内)。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<style>
*{
margin: 0;
padding: 0;
}
div .son{
color: #fff;
background: pink;
width: 200px;
line-height: 100px;
text-align:center;
margin: 30px;
}
</style>
<body>
<div id="father">
<div class="son">盒子1</div>
<div class="son">盒子2</div>
</div>
</body>
</html>
以上两个子元素 .son
均为浮动元素,所以父元素 #father
高度坍塌。给父元素激活 BFC,设置 overflow:hidden
,即可解决父元素高度坍塌的问题。
- 自适应多栏布局(BFC 的区域不会与 float 属性的盒子重叠,这种情况下可以触发生成新的 BFC) 。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<style>
*{
margin: 0;
padding: 0;
}
body {
width: 100%;
position: relative;
}
.left {
width: 100px;
height: 200px;
float: left;
background: pink;
text-align: center;
line-height: 200px;
font-size: 20px;
}
.right {
height: 400px;
background: gray;
text-align: center;
line-height: 400px;
font-size: 40px;
}
</style>
<body>
<div class="left">LEFT</div>
<div class="right">RIGHT</div>
</body>
</html>
以上代码中,元素 .left
发生浮动,脱离了文档流。与元素 .right
重叠。可以将元素 .right
触发 BFC(设置 overflow:hidden
)。使之成为自适应两栏布局。