BFC到底是什么?
1.在了解BFC前,我们先聊聊FC,
FC的全称是Formatting Context(格式化上下文),以下是官方文档对FC的解释
简单总结:元素在标准流里面都是属于一个FC,它可能是一个Block Formatting Context(BFC)或者Inline Formatting Context(IFC),但是只能是其中之一。块级元素的布局属于BFC, 行内级元素的布局属于IFC
2.BFC有什么作用?
我们来看一下官方文档对BFC作用的描述
简单概况如下:
- 在BFC中,box(块级元素)会在垂直方向上一个挨着一个的排布
- 垂直方向的间距由margin属性决定
- 在同一个BFC中,相邻两个box(块级元素)之间的margin会折叠(collapse)
- 在BFC中,每个元素的左边缘是紧挨着包含块的左边缘的
3.BFC的高度是auto的情况下,是如下方法计算高度的?
首先我们看一下官方文档的解释
简单总结一下:
- 如果只有inline-level,是行高的顶部和底部的距离
- 如果有block-level,是由最底层的块上边缘和最底层块盒子的下边缘之间的距离
- 如果有绝对定位元素,将被忽略
- 如果有浮动元素,那么会增加高度以包括这些浮动元素的下边缘
4.什么情况下会创建BFC?
- 根元素(HTML)
- 浮动元素(元素的 float 不是 none)
- 绝对定位元素(元素的 position 为 absolute 或 fixed)
- 行内块元素(元素的 display 为 inline-block)
- 表格单元格(元素的 display 为 table-cell,HTML表格单元格默认为该值),表格标题(元素的 display 为 table-caption,HTML表格标题默认为该值)
- 匿名表格单元格元素(元素的 display 为 table、table-row、 table-row-group、table-header-group、table-footer-group(分别是HTML table、
- row、tbody、thead、tfoot 的默认属性)或 inline-table)
- overflow 计算值(Computed)不为 visible 的块元素
- 弹性元素(display 为 flex 或 inline-flex 元素的直接子元素)
- 网格元素(display 为 grid 或 inline-grid 元素的直接子元素)
- display 值为 flow-root 的元素
5.BFC的实际应用
5.1解决margin的折叠问题
在上面提到,在同一个BFC中,相邻两个box(块级元素)之间的margin会折叠
我们通过代码来演示一下:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
body {
padding: 0;
margin: 0;
background-color: #ccc;
}
.box1 {
background-color: skyblue;
}
.box1 .box1-child {
height: 200px;
width: 500px;
background-color: purple;
margin-bottom: 20px;
}
.box2 {
height: 200px;
background-color: orange;
margin-top: 30px;
}
</style>
</head>
<body>
<div class="box1">
<div class="box1-child"></div>
</div>
<div class="box2"></div>
</body>
</html>
效果:
可以看到,box1-child元素和box2元素之间的margin为30px,因为他们都属于HTML创建的BFC环境中,margin发生了折叠
接下来看创建新的BFC会发生什么
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
body {
padding: 0;
margin: 0;
background-color: #ccc;
}
.box1 {
background-color: skyblue;
overflow: auto;
}
.box1 .box1-child {
height: 200px;
width: 500px;
background-color: purple;
margin-bottom: 20px;
}
.box2 {
height: 200px;
background-color: orange;
margin-top: 30px;
}
</style>
</head>
<body>
<div class="box1">
<div class="box1-child"></div>
</div>
<div class="box2"></div>
</body>
</html>
创建新的BFC后的效果:
上面这段代码通过给box1元素设置overflow: auto,使得box1元素创建了一个新的BFC,此时box1-child元素属于box1创建的BFC环境中,与HTML创建的BFC不为同一个,所以此时box1-child元素设置的margin-bottom不会与box2元素设置的margin-top产生折叠,从而解决了margin折叠的问题
5.2解决浮动高度塌陷问题
众所周知,当子元素设置了浮动,则子元素不会向父元素汇报高度,如果此时父元素没有设置高度(高度为auto),则父元素会产生高度塌陷
我们通过代码来演示一下:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
body {
padding: 0;
margin: 0;
background-color: #ccc;
}
.box {
background-color: skyblue;
}
.box .item {
float: left;
width: 200px;
height: 100px;
background-color: purple;
border: 1px solid #000;
}
</style>
</head>
<body>
<div class="box">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
</body>
</html>
效果:
此时,虽然我们给父元素(box)设置了背景颜色,但是由于他的子元素设置了浮动,不会汇报高度给他,导致他高度为0,所以并不能看见它的背景颜色
通过BFC解决浮动高度塌陷
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
body {
padding: 0;
margin: 0;
background-color: #ccc;
}
.box {
background-color: skyblue;
overflow: auto;
}
.box .item {
float: left;
width: 200px;
height: 100px;
background-color: purple;
border: 1px solid #000;
}
</style>
</head>
<body>
<div class="box">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
</body>
</html>
通过BFC解决浮动高度塌陷效果:
可以看到,我们给父元素(box)设置了overflow:auto后,box元素创建了新的BFC环境,通过上面第三点的第四条规则可以了解到,BFC环境中如果有浮动元素,那么会增加高度以包括这些浮动元素的下边缘,所以此时box元素有了高度,背景色也能显示出来了