BFC是什么呢?
BFC(Block Formatting Context)是块级格式化上下文
乍一听是不是非常的陌生。我们慢慢看。
首先当我们开发涉及到可视化布局的时候,经常会担心对于盒子的把控不好,很忌讳,怕影响到另一个盒子的布局,那么BFC的作用就出来了,他的本意就是一个环境中的元素不会影响到其它环境中的布局。
比如浮动元素也会形成BFC,浮动元素内部的子元素主要受该浮动元素影响,两个浮动元素之间是互不影响的。这里有点类似一个概念也就是说BFC就是一个独立的行政单位的意思。可以把它理解成是一个独立的容器,并且这个容器的里box的布局,与这个容器外的毫不相干。这就是BFC了。
我们先来看一个例子
(我的图片是每次刷新随机生成的,但是高度宽度不变的)
代码
<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>BFC</title>
<style>
.box {
background: cadetblue;
}
img {
float: left;
}
</style>
</head>
<body>
<h1>BFC</h1>
<div class="box">
<img src="https:picsum.photos/150/150">
<p>BFC的巧妙使用.....</p>
</div>
<div class="footer">我是footer</div>
</body>
</html>
看看浏览器
看到这里我们都很疑惑,为什么下面的footer跑后面来了。他不是块级标签吗
因为就是img用了左浮动,脱离了文档流,所以box盒子高度由p标签决定了,所以box盒子也就是只有p标签的高度。
那我们想要他的高度跟图片那么高,我们该怎么做呢?
那我们可以在样式里设置一个样式bfc并给box设置上,
<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>BFC</title>
<style>
.box {
background: cadetblue;
}
img {
float: left;
}
.bfc {
overflow: hidden;
}
</style>
</head>
<body>
<h1>BFC</h1>
<div class="box bfc">
<img src="https:picsum.photos/150/150">
<p>BFC的巧妙使用.....</p>
</div>
<div class="footer">我是footer</div>
</body>
</html>
看浏览器如何展示
可以看到这次符合我们的预期了,footer不会跑上去了,然后box标签也被撑大到盒子高度
为什么呢?
因为BFC会形成独立的渲染区域,控制内部元素不影响外部元素,所以例子中就是说,保证了img的浮动不会影响到外界元素,box的高度也等于img的高度。
但是我们去看一下p标签。
它占满了整个box盒子,在我们的认知中因为float的因素会让img也占一部分的,p占一部分的,但是p却占满了,不符合我们的常理,那么我们应该怎么做?
我们也给p标签加个bfc样式,所以,img标签也有了自己的宽度。
经过这样一顿操作,我们让其元素触发了BFC,达到了我们想要的布局。
除此之外还有什么可以触发BFC呢?
触发BFC
并不是任意一个元素都可以被当做BFC,只有当这个元素满足以下任意一个条件的时候,这个元素才会被当做一个BFC
下面是一些触发BFC的效果的小技巧
1.body根元素
2.设置浮动,不包括none
3.设置定位,absoulte或者fixed
4.行内块显示模式,inline-block
5.设置overflow,即hidden,auto,scroll
6.表格单元格,table-cell
7.弹性布局,flex
BFC举一反三
利用BFC解决外边距的塌陷问题(垂直塌陷)
demo代码
<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>BFC</title>
<style>
.box {
width: 150px;
height: 150px;
background-color: rgb(0, 60, 255);
margin: 50px;
}
.bfc {
overflow: hidden;
}
</style>
</head>
<body>
<h1>BFC</h1>
<div class="box"></div>
<div class="box"></div>
</body>
</html>
看浏览器
讲道理,我们在每个盒子都给了一个margin=50px,然后两个盒子应该是50+50=100才对的,但是它只有50px的间隔,所以这就是很典型的margin的塌陷,两段margin重叠到了一块,互相影响,那么我们可以通过BFC解决这个问题了
先将两个盒子各自用一个div盒子装起来,为什么这样做呢?因为我们说到BFC就是将它隔离起来,看代码
<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>BFC</title>
<style>
.box {
width: 150px;
height: 150px;
background-color: rgb(0, 60, 255);
margin: 50px;
}
.bfc {
overflow: hidden;
}
</style>
</head>
<body>
<h1>BFC</h1>
<div class="bfc">
<div class="box"></div>
</div>
<div class="bfc">
<div class="box"></div>
</div>
</body>
</html>
看浏览器
我们可以看到这个问题被解决了
总结
1、一个BFC区域只包含它的子元素,不包括它的孙子元素(子元素的子元素)。
2、不是所有的元素都能成为BFC区域,只有当这个元素满足条件的时候才会成为BFC区域。
3、不同的BFC区域之间是相互独立的,互不影响的。
4、利用这个特性我们可以让不同BFC区域之间的布局不产生影响,互不干扰