likes
comments
collection
share

CSS:深入理解 BFC 的概念以及创建方式

作者站长头像
站长
· 阅读数 9

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>

效果如下。

CSS:深入理解 BFC 的概念以及创建方式

会发现 .outer 的高度并不是直觉上的浮动元素高度,而只是跟浮动元素内部的文本对齐了。

处理这个问题,我们通常有两个方案。一个是使用 clearfix hack,还有一个就是为容器元素设置 overflow 属性,其值为 visible(默认值)以外的值,比如 overflow: auto

.outer {
      overflow: auto;
    }

再来看看效果。

CSS:深入理解 BFC 的概念以及创建方式

发现 .outer 的高度成功包含了浮动元素!

这里的知识点是:当我们给元素设置 overflow: visible 以外的值时,元素就创建了 BFC。

BFC 是一个完全独立的环境,为了不影响外部元素布局,就把浮动元素的高度包含了进来。

阻止浮动元素的围绕效果

还是上面的例子,当浮动元素的旁边的文本很多时,就会出现文字环绕效果。

CSS:深入理解 BFC 的概念以及创建方式

这也是浮动元素的一大特性,不过在左右布局场景就不合适了。这个时候就可以为文本元素创建 BFC。

.text {
      overflow: auto;
    }

就得到下面的理想效果。

CSS:深入理解 BFC 的概念以及创建方式

这一点也反应了 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>

效果如下。

CSS:深入理解 BFC 的概念以及创建方式

这里有两个地方产生了外边距合并:一个是 <p> 之间的外边距合并,一个是 <p> 与父元素 .outer 之间产生的外边距合并。前者是合理的,但父子元素之间的外边距合并结果就不是理想的。

父子元素之间的外边距合并意外导致了父元素高度塌陷。这个时候我们就可以通过给父元素创建 BFC 来解决这个问题。

.outer {
      background-color: #ccc;
      overflow: auto;
    }

效果如下。

CSS:深入理解 BFC 的概念以及创建方式

这一点还是反应了 BFC 是一个完全独立的环境,不会影响外部元素布局。

如何创建 BFC?

在介绍如何创建 BFC 前,先介绍一个特殊的 HTML 元素 <html>,也就是页面根元素。跟其他元素不同的时,<html> 天然就具备 BFC。

另外,如果其他元素想要创建 BFC,是需要通过设置特定 CSS 属性的方式来实现,这类属性有很多,我们只讲最常见的。

  • 首先,是 overflow 属性。当一个元素的 overflow 属性值不是 visibleclip 时,就会创建 BFC。比如:overflow: hiddenoverflow: auto
  • 其次,是浮动元素。即 float 属性值不为 none
  • 接着,是绝对定位元素(Absolutely positioned elements)。即 position 属性值是 absolutefixed
  • 然后,是 display 属性。当一个元素的 display 属性设置成 inline-blocktable-cell 时,就会创建 BFC。
  • 最后,是 Flex 项目和 Grid 项目。这要求它们的父元素设置了 display: flexdisplay: grid

以上,我们介绍了创建 BFC 的常见做法。

创建 BFC 的现代方法

不过,还有一种现代的创建 BFC 的方法没有介绍,那就是为元素设置 display: flow-root。当元素设置完这个属性后,就会创建 BFC。

display: flow-root 的作用类似于让当前元素具备跟 <html> 一样的 BFC 表现。不过,相比 clearfix hack 这类方法,display: flow-root 不会产生任何副作用。

目前,display: flow-root 在各大主流浏览器中也得到了完全支持,可以很安全地使用了。

CSS:深入理解 BFC 的概念以及创建方式

可能地话,你可以尽量使用 display: flow-root 来显式表明你是为了创建 BFC。

总结

本文我们介绍了 CSS 中 BFC 的概念。首先我按照自己的理解给出了 BFC 的定义。接着,介绍了 BFC 2 个最常应用的场景案例。最后,就如何创建 BFC 也做了说明。

希望本篇文章对大家能有所帮助。感谢阅读,再见。