CSS:深入理解 BFC 的概念以及创建方式
CSS 中“BFC”的概念,全称叫“Block Formatting Context”,中文叫“块级格式化上下文”。但从这个名字上,我们几乎读不到任何有效信息。
MDN 文档关于 BFC 的概念介绍 也是让人读不懂;前端界大佬 Rachel Andrew 在她的一篇 BFC 文章《Understanding CSS Layout And The Block Formatting Context》中,也是只字未提 BFC 的概念,只从实际使用入手,介绍 BFC 的适应场景。
最终,我从 geeksforgeeks.org 站点关于 BFC 描述中,获得了一些灵感,斗胆从自己的理解角度给出一个定义。
BFC 是一种特殊的上下文环境。当一个元素创建 BFC 后,就具备了一个完全独立的环境。
BFC 会影响当前元素和内部元素的布局表现,但不会影响跟外部元素之间的布局关系。
BFC 被用烂了的 2 个场景分别是清除浮动影响(clear the floats)和避免外边距合并(prevent margins collapsing)。
接下来,我们对这 2 个场景分别进行介绍,在实战中体会 BFC 的作用。
清除浮动影响
在 Flex 布局流行之前,网页上的布局大都使用浮动实现的。
浮动元素的高度被忽略
浮动特性的有一个坑,就是它的高度默认情况下会被父元素忽略。
以下面的 HTML 为例。
<div class="outer">
<div class="float">I am a floated element.</div>
<div class="text">I am text inside the outer box.</div>
</div>
<style>
.outer {
border: 5px dotted rgb(214,129,137);
}
.float {
padding: 10px;
}
</style>
效果如下。
会发现 .outer
的高度并不是直觉上的浮动元素高度,而只是跟浮动元素内部的文本对齐了。
处理这个问题,我们通常有两个方案。一个是使用 clearfix hack,还有一个就是为容器元素设置 overflow 属性,其值为 visible(默认值)以外的值,比如 overflow: auto
。
.outer {
overflow: auto;
}
再来看看效果。
发现 .outer
的高度成功包含了浮动元素!
这里的知识点是:当我们给元素设置 overflow: visible 以外的值时,元素就创建了 BFC。
BFC 是一个完全独立的环境,为了不影响外部元素布局,就把浮动元素的高度包含了进来。
阻止浮动元素的围绕效果
还是上面的例子,当浮动元素的旁边的文本很多时,就会出现文字环绕效果。
这也是浮动元素的一大特性,不过在左右布局场景就不合适了。这个时候就可以为文本元素创建 BFC。
.text {
overflow: auto;
}
就得到下面的理想效果。
这一点也反应了 BFC 是一个完全独立的环境,不会影响外部元素布局。
防止外边距合并
在布局中常常还会遇到的一个场景就是外边距合并。
我们再举一个例子。
<div class="outer">
<p>I am paragraph one and I have a margin top and bottom of 20px;</p>
<p>I am paragraph two and I have a margin top and bottom of 20px;</p>
</div>
<style>
.outer {
background-color: gray;
}
p {
margin: 20px 0 20px 0;
background-color: pink;
}
</style>
效果如下。
这里有两个地方产生了外边距合并:一个是 <p>
之间的外边距合并,一个是 <p>
与父元素 .outer
之间产生的外边距合并。前者是合理的,但父子元素之间的外边距合并结果就不是理想的。
父子元素之间的外边距合并意外导致了父元素高度塌陷。这个时候我们就可以通过给父元素创建 BFC 来解决这个问题。
.outer {
background-color: #ccc;
overflow: auto;
}
效果如下。
这一点还是反应了 BFC 是一个完全独立的环境,不会影响外部元素布局。
如何创建 BFC?
在介绍如何创建 BFC 前,先介绍一个特殊的 HTML 元素 <html>
,也就是页面根元素。跟其他元素不同的时,<html>
天然就具备 BFC。
另外,如果其他元素想要创建 BFC,是需要通过设置特定 CSS 属性的方式来实现,这类属性有很多,我们只讲最常见的。
- 首先,是
overflow
属性。当一个元素的overflow
属性值不是visible
、clip
时,就会创建 BFC。比如:overflow: hidden
、overflow: auto
。 - 其次,是浮动元素。即
float
属性值不为none
。 - 接着,是绝对定位元素(Absolutely positioned elements)。即
position
属性值是absolute
或fixed
。 - 然后,是
display
属性。当一个元素的display
属性设置成inline-block
或table-cell
时,就会创建 BFC。 - 最后,是 Flex 项目和 Grid 项目。这要求它们的父元素设置了
display: flex
或display: grid
。
以上,我们介绍了创建 BFC 的常见做法。
创建 BFC 的现代方法
不过,还有一种现代的创建 BFC 的方法没有介绍,那就是为元素设置 display: flow-root
。当元素设置完这个属性后,就会创建 BFC。
display: flow-root
的作用类似于让当前元素具备跟 <html>
一样的 BFC 表现。不过,相比 clearfix hack 这类方法,display: flow-root
不会产生任何副作用。
目前,display: flow-root
在各大主流浏览器中也得到了完全支持,可以很安全地使用了。
可能地话,你可以尽量使用 display: flow-root
来显式表明你是为了创建 BFC。
总结
本文我们介绍了 CSS 中 BFC 的概念。首先我按照自己的理解给出了 BFC 的定义。接着,介绍了 BFC 2 个最常应用的场景案例。最后,就如何创建 BFC 也做了说明。
希望本篇文章对大家能有所帮助。感谢阅读,再见。
转载自:https://juejin.cn/post/7340531314883854374