对BFC的简单理解
🙋 Hello,I'm IamZJT!
✍️ 一名菜鸟前端开发工程师!📦 Github地址:iamzjt-front-end。
🖐️ 欢迎点赞
➕star
,期盼与您并肩前行...
一、什么是BFC?如何应用?
- (Block formatting context) 块级格式化上下文;
- 一块独立渲染区域,内部元素的渲染不会影响边界以外的元素;
- 形成BFC的常见条件: float不是none; position是absolute或fixed; overflow不是visible; display是flex inline-block等;
- 常见应用:利用BFC避免margin重叠、自适应两栏布局、清除浮动。
二、BFC的特性和应用举例:
2.1 利用BFC避免margin重叠
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>防止margin重叠</title>
</head>
<style>
div{
width: 100px;
height: 100px;
background: lightblue;
margin: 100px;
}
</style>
<body>
<div></div>
<div></div>
</body>
</html>
从效果上看,因为两个 div 元素都处于同一个 BFC 容器下 (这里指 body 元素) 所以第一个 div 的下边距和第二个 div 的上边距发生了重叠,所以两个盒子之间距离只有 100px,而不是 200px。
首先这不是 CSS 的 bug,我们可以理解为一种规范,如果想要避免外边距的重叠,可以将其放在不同的 BFC 容器中。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>防止margin重叠</title>
</head>
<style>
.container {
overflow: hidden;
}
p {
width: 100px;
height: 100px;
background: lightblue;
margin: 100px;
}
</style>
<body>
<div class="container">
<p></p>
</div>
<div class="container">
<p></p>
</div>
</body>
</html>
这时候,两个盒子边距就变成了 200px
2.2 自适应两栏布局
根据:
- 每个盒子的margin box的左边,与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<style>
.left {
height: 100px;
width: 100px;
float: left;
background: lightblue;
}
.right {
height: 300px;
background: #eee;
}
</style>
<body>
<div class="left">我是一个左浮动的元素</div>
<div class="right">我是一个没有设置浮动, 也没有触发 BFC 元素</div>
</body>
</html>
这时候其实第二个元素有部分被浮动元素所覆盖,(但是文本信息不会被浮动元素所覆盖) 如果想避免元素被覆盖,可触第二个元素的 BFC 特性,在第二个元素中加入 overflow: hidden,就会变成:
这个方法可以用来实现两列自适应布局,效果不错,这时候左边的宽度固定,右边的内容自适应宽度。
2.3 清除浮动
当我们不给父节点设置高度,子节点设置浮动的时候,会发生高度塌陷,这个时候我们就要清除浮动。
比如这样:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>清除浮动</title>
</head>
<style>
.parent {
border: 1px solid #000;
}
.child {
width: 100px;
height: 100px;
background: #eee;
float: left;
}
</style>
<body>
<div class="parent">
<div class="child"></div>
</div>
</body>
</html>
由于容器内元素浮动,脱离了文档流,所以容器只剩下 2px 的边距高度。如果使触发容器的 BFC,那么容器将会包裹着浮动元素。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>清除浮动</title>
</head>
<style>
.parent {
border: 1px solid #000;
overflow: hidden
}
.child {
width: 100px;
height: 100px;
background: #eee;
float: left;
}
</style>
<body>
<div class="parent">
<div class="child"></div>
</div>
</body>
</html>
扩展1:清除浮动有哪几种常见方法?
-
额外标签法,在子元素的末尾加上一个标签(
<div style="clear: both"></div>
),其中要求这个标签必须是块级元素; -
父级添加overflow属性:auto、hidden、scroll;
-
父级添加after伪元素;
.clearfix::after { content: ""; display: block; clear: both; }
-
父级添加双伪元素
.clearfix::before, .clearfix::after { content: ""; dispaly: table; } .clearfix::after { clear: both; }
扩展2:
上面写到了两栏自适应布局,也就是左侧固定,右侧自适应布局,目前我有两个思路。
思路1:跟上面一样,给右侧元素添加overflow:hidden,形成BFC;
思路2:从圣杯布局中启发而来,将left和right一起放进container盒子中,左侧盒子float:left浮动,然后给container设置padding-left值,最后给left设置margin-left负值,大功告成。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>左侧固定,右侧自适应</title>
<style>
.left {
width: 200px;
height: 100px;
background-color: pink;
float: left;
margin-left: -200px;
}
.right {
width: 100%;
height: 500px;
background-color: skyblue;
}
.container {
padding-left: 200px;
}
</style>
</head>
<body>
<div class="container">
<div class="left">这是左侧</div>
<div class="right">这是右侧</div>
</div>
</body>
</html>
ps
🎯 如果您看到这里,请不要走开。
🎉 这是一个早起俱乐部:三更灯火五更鸡!
⭐️ 寻找 志同道合 的小伙伴,我们一起 早起
。