BFC(Block Formatting Context):块级格式化上下文
预备知识
在了解 BFC 之前,我们先来了解 Box 和 Fomatting Context
Box 盒子模型
- 块级元素(block-level box):块盒 + 行块盒
display: block / list-item / inline-block / table
的元素是块级元素,并且参与 BFC
行内元素(inline-level box):行盒
W3C CSS2.1 规范中的 FC
- BFC
- IFC
- W3C CSS3 规范中新增的 FC
- GFC — grid
- FFC — flex
BFC
1. BFC 的定义
W3C 官方解释为:BFC 它决定了元素如何对其内容进行定位,以及与其它元素的关系和相互作用,当涉及到可视化布局时,Block Formatting Context 提供了一个环境,HTML 在这个环境中按照一定的规则进行布局。
简单来说就是,BFC 是一个完全独立的空间(布局环境),让空间里的子元素不会影响到外面的布局。
2. BFC 的触发
body 元素就是 BFC
举例会触发 BFC 的 css 属性
overflow: 不为 visible
float: 不为 none
position: absolute / fixed
display: inline-block / table / table-caption
display:table
也认为可以生成 BFC,其实这里的主要原因在于 Table 会默认生成一个匿名的 table-cell,正是这个匿名的 table-cell 生成了 BFC
3. BFC 的约束规则
- BFC 就是一个块级元素,块级元素会在垂直方向一个接一个的排列
- BFC 就是页面中的一个隔离的独立容器,容器里的标签不会影响到外部标签
- 垂直方向的距离由 margin 决定, 属于同一个 BFC 的两个相邻的标签外边距会发生重叠
- 计算 BFC 的高度时,浮动元素也参与计算
- BFC 的区域不会与 float 的元素区域重叠
常规流布局的约束规则
- Block 元素会扩展到与父元素同宽,所以block元素会垂直排列
- 垂直方向上的两个相邻 DIV 的 margin 会重叠,而水平方向不会(此规则并不完全正确)
- 浮动元素会尽量接近往左上方(或右上方)
- 为父元素设置
overflow:hidden
或浮动父元素,则会包含浮动元素
4. BFC 的应用
4.1 防止 margin 重叠(坍塌)
嵌套元素 margin 重叠
<!DOCTYPE html>
<html lang="en">
<head>
<style>
body {
margin: 0
}
.box {
margin-top: 20px;
}
.a,.b {
display: inline-block; /* 触发 BFC */
width: 100px;
}
.a {
background-color: red;
height: 50px;
}
.b {
background-color: aqua;
height: 20px;
margin-top: 5px;
}
</style>
</head>
<body>
<div class="box">
<div id="a" class="a">
<div id="b" class="b"></div>
</div>
</div>
</body>
</html>
相邻元素垂直方向 margin 重叠
<!DOCTYPE html>
<html lang="en">
<head>
<style>
body {
margin: 0;
}
.background {
background-color: aqua;
}
p {
color: #f55;
background: #fcc;
width: 100px;
text-align: center;
margin: 20px;
}
.bfc {
display: inline-block; /* 触发 BFC */
}
</style>
</head>
<body>
<div class="background bfc">
<p class="bfc">Haha</p>
<p>Hehe</p>
</div>
</body>
</html>
4.2 清除内部浮动
<!DOCTYPE html>
<html lang="en">
<head>
<style>
body {
margin: 0;
}
.par {
border: 5px solid #fcc;
width: 200px;
}
.child {
border: 5px solid #f66;
width: 50px;
height: 50px;
float: left;
}
.bfc {
/*overflow: hidden;*/ /* 触发 bfc */
}
</style>
</head>
<body>
<div class="par bfc">
<div class="child"></div>
<div class="child"></div>
</div>
</body>
</html>
4.3 自适应多栏布局
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
body {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
div {
height: 100px;
}
.left {
background: pink;
float: left;
width: 180px;
}
.center {
background: lightyellow;
overflow: hidden; /* 触发 bfc */
}
.right {
background: lightblue;
width: 180px;
float: right;
}
</style>
</head>
<body>
<div class="container">
<div class="left"></div>
<div class="right"></div>
<div class="center"></div>
</div>
</body>
</html>