前言
为什么要写这篇文章,因为网上一搜你会发现,除了雷同,更多的是乏味,难懂,概念满天飞。我不否认这样写的好处,但也请允许我为 BFC 添盐加醋,即使依旧乏味,好歹也算一出。
这里分成三分部来讲解 BFC 。BFC 不是什么遥远的东西,只要你做前端,它一直都在你身旁,只是很多时候,你没注意到,或者不知道这就是跟 BFC 有关。有些东西就是这样,不知不觉地就经历了,但当你反应过来其实也不晚,只是会感叹一句:“原来如此”。
BFC 是什么
BFC 是一个独立的渲染区域。
什么叫独立?
独立就是不受外界影响,也不会影响外界,与世隔绝的那种。就像我们是一个独立的人一样,可以不受外界的影响。但.......,我怎么感觉这样比喻很牵强???嗯,你懂的!反正 BFC 所说的独立比我们人类中的所谓独立要纯粹得多。
渲染区域又是什么?
就是渲染的区域啊,我还能说啥呢!嗯,说点吧!
渲染就是你隔着屏幕看到的东西,区域就是指定的一块,不管大或小,说白了就是元素包裹的区域,随便打开一个网页,都不会让你失望。
而这个所谓的区域又有自己的一套渲染规则,在它里面的元素只能乖乖地任由它按这个渲染规则摆布,没有一点商量的余地。
BFC 有什么用
有了 BFC 我们就可以利用它来解决一些问题。比如:浮动导致的父元素高度坍塌,甚至我们还可以利用 BFC 的特性来实现多栏自适应布局。
-
浮动导致的父元素高度坍塌利用了【计算BFC的高度时,浮动元素也参与计算】这一特性实现的。
-
实现多栏自适应布局是利用了【BFC的区域不会与float box重叠】这一特性实现的。
-
外边距重叠(取最大的外边距值),可利用【BFC 是一个独立的区域】这一特性来解决。
下面是几个例子,由于 overflow: hidden 也是会触发生成 BFC 的方法之一,所以下面的例子都以它作为示例,更多可创建 BFC 的方法或者条件会在最后的 BFC 创建方法一小节中一一列出,现在我们先看例子:
高度坍塌
<!DOCTYPE html>
<html lang="en">
<style>
.box{
background-color: antiquewhite;
}
p {
float: left;
}
.bfc {
overflow: hidden;
}
</style>
<body>
<div class="box bfc">
<p>第一个</p>
<p>第二个</p>
</div>
</body>
</html>
浮动我们平时都用得也多,并且解决因浮动所带来的问题(高度坍塌)我们也是会不知为什么很自然的加上 overflow: hidden 来解决。现在你可知道为什么了吧!这个就是我所说的不经意中的其实一个。
两栏自适应
<!DOCTYPE html>
<html lang="en">
<style>
aside {
background-color: antiquewhite;
width:200px;
height: 300px;
}
.left{
float: left;
}
main{
height: 300px;
background-color: darkgrey;
}
.bfc {
overflow: hidden;
}
</style>
<body>
<div class="box">
<aside class="left">左侧</aside>
<main class="bfc">主区域</main>
</div>
</body>
</html>
这种两栏自适应的场景实现太常见了,小心面试的时候被问题。
多栏自适应
<!DOCTYPE html>
<html lang="en">
<style>
aside {
background-color: antiquewhite;
width:200px;
height: 300px;
}
.left{
float: left;
}
.right{
float: right;
}
main{
height: 300px;
background-color: darkgrey;
}
.bfc {
overflow: hidden;
}
</style>
<body>
<div class="box">
<aside class="left">左侧</aside>
<aside class="right">右侧</aside>
<main class="bfc">主区域</main>
</div>
</body>
</html>
注意:上面的 main 元素要放到最后面,不然就不会出现三足鼎立的局面。
外边距重叠
很常见,比如不加任何修饰(样式)的相邻的 p 标签,或者 ul 内相邻的 li 标签(如果有外边距),不仅仅是相邻的标签,父子标签也会出现外边距重叠。
相邻外边距重叠:
<!DOCTYPE html>
<html lang="en">
<style>
p {
margin: 28px 0;
}
.bfc {
overflow: hidden;
}
</style>
<body>
<p>第一个</p>
<div class="bfc">
<p>第二个</p>
</div>
</body>
</html>
这里就使用了【BFC 是一个独立的区域】这一特性。
如果你没遇到过所谓的相邻边距重叠,那直接把类名 bfc 的那个 div 删除就可以看到效果了(下同)。
父子边距重叠
<!DOCTYPE html>
<html lang="en">
<style>
.box{
background-color: antiquewhite;
}
main{
margin-top: 28px;
height: 300px;
background-color: darkgrey;
}
.bfc {
overflow: hidden;
}
</style>
<body>
<div class="box">
<div class="bfc">
<main >主区域</main>
</div>
</div>
</body>
</html>
我们在 main 元素外加了一层,并让它拥有 bfc 特性。这样就可以解决父子元素之间的边距重叠的问题了。但有时候我并不想多添加一个元素。那怎么办呢?可以给父元素添加一个值大于 0 边框或者内边距的可以了,比如:padding: 0.1px 。
BFC 特性归纳
BFC 特性也没多少条,列出来就完了:
- BFC 是一个独立的区域
- 计算 BFC 的高度时,浮动元素也参与计算
- BFC 的区域不会与 float box 重叠
- 同属一个 BFC 内两个相邻的 Box(元素)边距(margin)会发生重叠
BFC 创建方法
那么怎么才能创建一个 BFC 呢?其实这个也不需要怎么理解,你只需要记住就行,有些东西不是理解万岁,而是王非的那首歌 《约定》,静静地放在心里就好。
- 根元素(html)
- float 的值不是 none(比如:float: left,float: right)
- position 的值不是 static 或者 relative(比如:position: fixed,position: absolute)
- display 的值是 inline-block、table-cell、flex、table-caption 或者 inline-flex
- overflow 的值不是 visible (比如:overflow: auto,overflow: hidden)
上面的几个 CSS 属性不要告诉你不没听过,不然......,不然,哼,我会相信的。
最后
现在是不是有一种不过如此的感觉,这就对了。