什么是BFC
BFC(Block formatting context)直译为"块级格式化上下文"。它是一个独立的渲染区域,只有Block-level box参与, 它规定了内部的Block-level Box如何布局,并且与这个区域外部毫不相干。
BFC是一个独立的布局环境,其中的元素布局是不受外界的影响,并且在一个BFC中,块盒与行盒(行盒由一行中所有的内联元素所组成)都会垂直的沿着其父元素的边框排列。
BFC的布局规则
-
内部的Box会在垂直方向,一个接一个地放置。
-
Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠。(相邻两个div默认也是这样,取两者中的最大值,而不是两个margin相加)
-
每个盒子(块盒与行盒)的margin box的左边,与包含块border box的左边相接触(对于从左往右的格式化,否则相反),即使存在浮动也是如此。
-
BFC的区域不会与float box重叠。
-
BFC在页面上是一个独立的容器,它外边的元素不会影响它里边的元素,里边的元素也不会影响它外边的元素
-
计算BFC的高度时,浮动元素也参与计算。
如何创建BFC
- 浮动元素:float除none以外的值
- 定位元素:position除static、relative以外的值(absolute、fixed)
- overflow除visible以外的值(hidden、auto、scroll)
- display为inline-block、table-cells(跟table相关的那几个)、flex
BFC的作用
1、利用BFC解决margin重叠问题
相邻两个div默认margin会发生重叠,取两者中的最大值
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>BFC</title>
<style>
*{
margin: 0;
padding: 0;
}
.top{
width: 200px;
height: 200px;
background: red;
margin-bottom: 40px;
}
.bottom{
width: 200px;
height: 200px;
background: blue;
margin-top: 60px;
}
</style>
</head>
<body>
<div class="top"></div>
<div class="bottom"></div>
</body>
</html>
当给红色块下外边距margin-bottom设置40px,给蓝色块上外边距margin-top设置60px时,上下外边距会发生重叠,两个色块的间距解析为两者中的较大值60px
根据第二条规则,属于同一个BFC的两个相邻的Box会发生margin重叠,所以我们可以设置它们所处两个不同的BFC,也就是我们可以让把第二个div用div包起来,然后激活它使其成为一个BFC
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>BFC解决margin重叠</title>
<style>
*{
margin: 0;
padding: 0;
}
.top{
width: 200px;
height: 200px;
background: red;
margin-bottom: 40px;
}
.bottom{
width: 200px;
height: 200px;
background: blue;
margin-top: 60px;
}
.box{
overflow: hidden;
}
</style>
</head>
<body>
<div class="top"></div>
<div class="box">
<div class="bottom"></div>
</div>
</body>
</html>
通过给蓝色块添加父元素.box并设置样式overflow:hidden;使得父元素.box创建了BFC,此时红色块和蓝色块属于不同的BFC,红色块的BFC仍然是根元素<html>,蓝色块的BFC是父元素.box。从而解决了两者的上下margin重叠问题。
2、利用BFC清除浮动,解决父元素高度塌陷问题
当我们不给父节点设置高度,子节点设置浮动的时候,会发生高度塌陷,这个时候我们就要清除浮动。
<!DOCTYPE html>
<html>
<head>
<title>BFC清除浮动</title>
<style>
*{
margin: 0;
padding: 0;
}
.par {
border: 10px solid greenyellow;
width: 300px;
}
.child {
border: 5px solid blue;
width:100px;
height: 100px;
float: left;
}
</style>
</head>
<body>
<div class="par">
<div class="child"></div>
<div class="child"></div>
</div>
</body>
</html>
我们根据最后一条规则(计算BFC的高度时,浮动元素也参与计算),给父元素创建BFC
<!DOCTYPE html>
<html>
<head>
<title>BFC清除浮动</title>
<style>
*{
margin: 0;
padding: 0;
}
.par {
border: 10px solid greenyellow;
width: 300px;
overflow: hidden;
}
.child {
border: 5px solid blue;
width:100px;
height: 100px;
float: left;
}
</style>
</head>
<body>
<div class="par">
<div class="child"></div>
<div class="child"></div>
</div>
</body>
</html>
给父元素.par设置样式overflow:hidden;使得父元素.par创建了BFC,而BFC规定“计算BFC高度时浮动元素也参于计算”,此时子元素.child虽然设置了浮动,但其高度仍计算至父元素内,从而解决了高度塌陷问题
3、实现自适应两栏布局
根据(每个盒子的margin box的左边,与包含块border box的左边相接触(对于从左往右的格式化,否则相反),即使存在浮动也是如此)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>BFC实现两栏布局</title>
<style>
*{
margin: 0;
padding: 0;
}
.left{
width: 100px;
height: 200px;
background: yellowgreen;
float: left;
text-align: center;
line-height: 200px;
font-size: 20px;
}
.right{
height: 300px;
background: blue;
text-align: center;
line-height: 300px;
font-size: 40px;
}
</style>
</head>
<body>
<div class="left">left</div>
<div class="right">right</div>
</body>
</html>
根据(BFC的区域不会与float box重叠),所以我们让right单独成为一个BFC
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>BFC实现两栏布局</title>
<style>
*{
margin: 0;
padding: 0;
}
.left{
width: 100px;
height: 200px;
background: yellowgreen;
float: left;
text-align: center;
line-height: 200px;
font-size: 20px;
}
.right{
height: 300px;
background: blue;
text-align: center;
line-height: 300px;
font-size: 40px;
overflow: hidden;
}
</style>
</head>
<body>
<div class="left">left</div>
<div class="right">right</div>
</body>
</html>
right会自动的适应宽度,这时候就形成了一个两栏自适应的布局。
总结
BFC在页面上是一个独立的容器,它外边的元素不会影响它里边的元素,里边的元素也不会影响它外边的元素。
因为BFC内部的元素和外部的元素绝对不会互相影响,因此, 当BFC外部存在浮动时,它不应该影响BFC内部Box的布局,BFC会通过变窄,而不与浮动有重叠。同样的,当BFC内部有浮动时,为了不影响外部元素的布局,BFC计算高度时会包括浮动的高度。避免margin重叠也是一个道理。
参考经典好文:https://blog.csdn.net/sinat_36422236/article/details/88763187