学习BFC之前先复习一些概念
1、普通流:
- 元素按照其在HTML中的先后位置自上而下布局。
- 行内元素水平排列,直到当行被占满然后换行,块级元素则被渲染为完整的一个新行
- 所有元素默认都是普通流布局
2、浮动:元素首先按照普通流的位置出现,然后根据浮动的方向尽可能向左边或右边偏移
3、绝对定位:元素会整体脱离普通流,因此绝对定位元素不会对其兄弟元素造成影响
一、什么是BFC?
BFC属于普通流。BFC全称是Block Formatting Context,意思就是块级格式化上下文。你可以把BFC看做元素的一个属性,当元素拥有的BFC属性,这个元素就可以看作是隔离了的独立容器,容器里边的元素不会影响到容器外部的元素。
二、BFC作用
- 形成独立的渲染区域
- 内部元素的渲染不会影响外界
三、形成BFC的条件
- html根元素;
- float(不为none即可):left、right;
- position:absolute、fixed;
- display:inline-block、flex、inline-flex、grid、inline-grid、flow-root;
- overflow(除了 visible 以外的值): hidden、auto、scroll
- overflow: hidden;
- display: flex;
- display: inline-flex;
- display: inline-block;
- position: absolute;
- position: fixed;
Tip:记住这几个常用的就可以了。
提醒:display:flow-root; 该元素生成一个块级元素盒,其会建立一个新的块级格式化上下文,定义格式化上下文的根元素。所以它不会产生任何副作用,所以用display:flow-root; 创建BFC也是一个很好的选择
举个栗子(重要!让你理解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>
.container {
background-color: #ccc;
}
.container img {
width: 300px;
}
</style>
</head>
<body>
<h1>理解BFC</h1>
<div class="container">
<img src="./avator2.webp" alt="">
<p>这次一定要...</p>
</div>
</body>
</html>
效果图:
我们让图片左浮动 :
<!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>
.container {
background-color: #ccc;
}
.container img {
float: left; //左浮动
width: 300px;
}
</style>
</head>
<body>
<h1>理解BFC</h1>
<div class="container">
<img src="./avator2.webp" alt="">
<p>这次一定要...</p>
</div>
</body>
</html>
效果图:
然后我们发现存在一个问题,container高度变成了21px,之所以只有21px,是因为图片左浮动了,脱离了我们文档流,container高度是由p标签撑起来的,而container盒子是父元素,正常情况下高度应该是跟图片一样高。这时候就可以用到BFC的概念:
我们可以给container加一个overflow:hidden;就可以让图片撑起container高度了:
<!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>
.container {
background-color: #ccc;
}
.container img {
float: left;
width: 300px;
}
.bfc {
overflow: hidden; //设置BFC
}
</style>
</head>
<body>
<h1>理解BFC</h1>
<div class="container bfc"> //设置BFC
<img src="./avator2.webp" alt="">
<p>这次一定要...</p>
</div>
</body>
</html>
这时候container高度就是图片的高度,为什么呢?因为BFC元素会形成独立的渲染区域,来保证内部元素的渲染不会影响外界。现在的BFC元素就是container,img就是BFC内部的元素,所以此时container会保证img的渲染不会影响外界。
但其实我们还存在一个问题: 把鼠标放在p标签上,会发现p标签的宽度占满了整个容器宽度。
实际上p标签的宽度是要除了图片宽度之外的宽度,那我们要怎么做呢?我们给p标签也设置overflow:hidden;就好了
因为给p标签设置了BFC(就是添加了overflow:hidden;),p标签就会形成一个独立的渲染区域(宽度不能延申到img那里,只能在自己地盘渲染)
四、BFC应用场景
1、解决当父级元素没有高度时,子级元素浮动会使父级元素高度塌陷的问题
就是上面那个例子
2、解决子级元素外边距会使父级元素塌陷的问题
<!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 {
margin: 0;
padding: 0;
}
.continer{
width: 100px;
height: 200px;
background: pink;
}
.box{
margin-top: 50px;
height: 50px;
width: 50px;
background: skyblue;
}
</style>
</head>
<body>
<div class="continer">
<div class="box"></div>
</div>
</body>
</html>
解决前运行结果,父元素跟着子元素塌陷:
任何让我们给父元素设置BFC(添加overflow:hidden;)
<!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 {
margin: 0;
padding: 0;
}
.continer{
width: 100px;
height: 200px;
background: pink;
overflow: hidden; //设置BFC
}
.box{
margin-top: 50px;
height: 50px;
width: 50px;
background: skyblue;
}
</style>
</head>
<body>
<div class="continer">
<div class="box"></div>
</div>
</body>
</html>
Tip: 当然这个问题也可以通过将子级元素的margin-top改为父级元素的padding-top来解决。