参考链接:
10 分钟理解 BFC 原理 https://zhuanlan.zhihu.com/p/25321647
10分钟复习CSS盒模型与BFC https://www.imooc.com/article/43233
CSS学习笔记——深入理解BFC https://www.imooc.com/article/9723
什么是BFC
首先解释一下FC,Formatting Context,格式化上下文,指页面中一个渲染区域,拥有一套渲染规则,它决定了其子元素如何定位,以及与其他元素的相互关系和作用。
BFC即Block Formatting Contexts(块级格式化上下文),它是W3C CSS2.1规范中的一个概念,它决定了元素如何对其内容进行定位,以及与其他元素的关系和相互作用。
通俗的说:BFC是一个独立的布局环境,我们可以理解为一个箱子(实际是看不见摸不着的),箱子内部的元素无论怎么翻江倒海,都不会影响到外部。转换为BFC理解则是:BFC中的元素的布局不受外界的影响(我们往往利用这个特性来消除浮动元素对其非浮动的兄弟元素和其子元素带来的影响)。并且在一个BFC中,块盒与行盒(行盒由一行中所有的内联元素所组成)都会垂直的沿着其父元素的边框排列。
BFC布局规则
1、在BFC下,内部的box会在垂直方向,一个接一个的放置;
2、box垂直方向的距离由margin决定,属于同一个BFC的两个相邻box的margin会发生重叠;
3、在BFC中,每一个盒子的左外边缘(margin-left)会触碰到容器的左边缘(border-left),对于从右到左的格式来说,则触碰到右边缘(border-right),即使存在浮动也是如此;
4、BFC的区域不会与float box重叠;
5、计算BFC的高度时,浮动元素也参与计算。
如何触发BFC
1、根元素(body)或包含根元素的元素;
2、浮动元素(float除了none以外的值);
3、绝对定位元素(元素的position为absolute或fixed);
4、overflow(除了visible以外的值,hidden、auto、scroll);
5、display为inline-block、table-cells、flex;
BFC的应用
1、同一个BFC下外边距会发生重叠
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>BFC</title>
<style type="text/css">
div{
width:100px;
height:100px;
background: pink;
margin:100px;
}
</style>
</head>
<body>
<div></div>
<div></div>
</body>
</html>
box垂直方向的距离由margin决定,属于同一个BFC的两个相邻box的margin会发生重叠;
这里的两个div元素同处于一个BFC容器下(body元素),所以这第一个div的下边距和第二个div的上边距发生了重叠,两个盒子之间的距离只有100px,并非200px。
解决这个问题,需要将两个div分属于两个不同的BFC元素:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>BFC</title>
<style type="text/css">
.bfc{
overflow: hidden; //触发BFC
}
p{
width:100px;
height:100px;
background: pink;
margin:100px;
}
</style>
</head>
<body>
<div class="bfc">
<p></p>
</div>
<div class="bfc">
<p></p>
</div>
</body>
</html>
这里两个盒子之间的边距就变为了200px。
2、BFC可以清除浮动
由于浮动的元素会脱离普通文档流,所以:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>BFC清除浮动</title>
<style type="text/css">
.parent{
width:200px;
border:1px solid #000;
}
.child{
width:100px;
height:100px;
background: pink;
float:left;
}
</style>
</head>
<body>
<div class="parent">
<div class="child"></div>
</div>
</body>
</html>
由于容器内的子元素浮动,脱离了文档流,导致父元素高度塌陷,所以外层容器只剩下2px的容器高度。
可以使用BFC包裹浮动元素
计算BFC的高度时,浮动元素也参与计算。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>BFC清除浮动</title>
<style type="text/css">
.parent{
width:200px;
border:1px solid #000;
overflow: hidden; //触发BFC
}
.child{
width:100px;
height:100px;
background: pink;
float:left;
}
</style>
</head>
<body>
<div class="parent">
<div class="child"></div>
</div>
</body>
</html>
3、实现自适应两栏布局
BFC可以阻止浮动元素覆盖被浮动元素,我们可以使用这一特性来实现自适应两栏布局。
如果不设置BFC,会出现下面的情况
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>BFC实现自适应布局</title>
<style type="text/css">
.left{
width:100px;
height:100px;
float:left;
background: pink;
}
.right{
width:200px;
height:200px;
background: lightblue;
}
</style>
</head>
<body>
<div class="left">我是一个浮动元素,我浮动在左边</div>
<div class="right">我不是浮动元素,我也没有触发BFC,我在右边</div>
</body>
</html>
由于浮动导致左边的元素脱离文档流,所以右边的元素自然向左移动,导致有部分元素被浮动元素覆盖;
也是因为
在BFC中,每一个盒子的左外边缘(margin-left)会触碰到容器的左边缘(border-left),对于从右到左的格式来说,则触碰到右边缘(border-right),即使存在浮动也是如此;
解决这个问题,可以出发右边元素的BFC特性,在右边元素中添加overflow:hidden;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>BFC实现自适应布局</title>
<style type="text/css">
.left{
width:100px;
height:100px;
float:left;
background: pink;
}
.right{
width:200px;
height:200px;
background: lightblue;
overflow:hidden;
}
</style>
</head>
<body>
<div class="left">我是一个浮动元素,我浮动在左边</div>
<div class="right">我不是浮动元素,我触发BFC,我在右边</div>
</body>
</html>
BFC的区域不会与float box重叠;
这样就可以实现两列自适应,去掉右边的宽度,就可以实现左边宽度固定,右边宽度自适应的两列自适应布局。