温故|试试倒过来学BFC?

3,167 阅读6分钟

温故|试试倒过来学BFC?

前言

tips:每个技术点都值得优写:4期

在交谈 BFC 的时候,谈论产生 BFC 的条件,或 BFC 的特性,比起说什么是 BFC,可能更有意义。

倒过来学 BFC,可能会更有助于掌握 BFC,所以我们先谈 BFC 的特性,理解它的特性, 如果感兴趣,或者觉得这种特性有帮助,再去追问产生 BFC 的条件,到了这里, 其实我们已经基本了解 BFC 了,此时我们再从文字总结的角度去归纳整理下 BFC 的概念。 这个顺序去学 BFC 可能会好一点,要不然 BFC 啥玩意? 块格式化上下文(Block Formatting Context,BFC),有点懵。

学习块格式化上下文(Block Formatting Context,BFC),主要学什么?

①一个理解。首要是理解 BFC 的特性。

②一个知道。其次是知道 BFC 的产生条件。

③一个了解。最后是了解 BFC 的概念。

BFC 的特性与作用

要说 BFC 的特性,我的理解就一个:“独立隔离性”,请注意这仅仅是我的理解。

因为 BFC 会创建一个独立的渲染区域,也就是一个独立的上下文环境, 而这个区域的特别就在于具有独立性,也具有“隔离性”。这个“独立隔离性”, 在一些场景尤为明显。下面举例说明 BFC 的特性:“独立隔离性”。

tips:如果利用 BFC 的特性能做一些有用的事,那么这就是 BFC 的作用了吧。 所以,谈特性往往离不开作用,对吗?那么此时,特性亦为作用。

1.阻止外边距折叠

像下面这样,两个相邻的兄弟元素会发生外边距折叠。

<div class="box1">第一行元素</div>
<div class="box2">第二行元素</div>
.box1 {
    background: #9cdf65;
    margin-bottom: 20px;
    height: 50px;
}

.box2 {
    background: #1e87f0;
    margin-top: 20px;
    height: 50px;
}

ae760d8c5261ce3d76b288caace05be.png

这里利用 overflow:hidden 解决这个问题,给 box1 或 box2所在元素,添加一个父 div, 并在该父 div 上设置 overflow: hidden。外边距折叠就不会再发生。

<div class="box1">第一行元素</div>
<div class="parent-box">
    <div class="box2">第二行元素</div>
</div>
.parent-box {
    /*给box1 或 box2 添加一个父元素,并使用overflow: hidden创建 BFC*/
    overflow: hidden;
}

.box1 {
    background: #9cdf65;
    margin-bottom: 20px;
    height: 50px;
}

.box2 {
    background: #1e87f0;
    margin-top: 20px;
    height: 50px;
}

image.png

当然这种简单的布局,更好的避免外边距折叠的办法是只设置上方元素top或bottom,这也是一个好习惯。 在这举例只是为了论证 BFC 的特性。也许在更加复杂的布局中,才能彰显 BFC 的价值。

tips:注意,直接在两个相邻的块级兄弟元素上加 overflow: hidden,折叠还是会发生。 需要先给两个元素之一添加父元素,并在该父元素上加 overflow: hidden, 才会创建 BFC 阻止外边距折叠的发生。

2.清除外部浮动

这里是一个清除外部浮动的例子,通过 display: flow-root, 为元素创建 BFC,从而实现清除元素外部浮动覆盖的影响。

先看下效果图

image.png

下面是相关代码

<section>
    <div class="float">浮动元素</div>
    <div class="box">普通块级元素</div>
</section>
<section>
    <div class="float">浮动元素</div>
    <div class="box flow-root">利用 display:flow-root 创建BFC</div>
</section>
section {
    height: 150px;
}

.box {
    border: 1px solid #397bb2;
}

.flow-root {
    border: 1px solid #397bb2;
    display: flow-root;
}

.float {
    float: left;
    width: 200px;
    height: 100px;
    border: 1px solid #0e0e0e;
    margin-right: 10px;
}

这里举例 BFC 具有清除 BFC 区域外部浮动的影响避免重叠的特性, 同样的关于浮动,也具有包含内部浮动的特性, 这种包含的意思是说不让 BFC 区域内的浮动元素“越界”影响区域外的布局, 使其被浮动被限制于 BFC 区域内。

3.BFC 特性小结

所以呢,BFC 具有阻止外边距折叠,清除浮动影响避免 BFC 区域与浮动元素重叠的特性, 当然还有别例子,但这些应该都体现了 BFC 区域具有“独立隔离性”, 即 BFC 区域内部元素的布局,不会“越界”影响外部元素的布局; 外部元素的布局也不会“穿透”,影响 BFC 区域的内部布局。

BFC 的产生条件

  • 根元素()天然就会创建 BFC,iframe 会创建一个 html,所以 iframe 也会天然创建 BFC。
  • 浮动元素(float 值不为 none),float 的默认值是 none。
  • 绝对定位元素(position 值为 absolute 或 fixed),position 的默认值是 static。
  • 行内块元素(display 值为 inline-block)
  • 表格单元格(display 值为 table-cell,HTML表格单元格默认值)
  • 表格标题(display 值为 table-caption,HTML表格标题默认值)
  • 匿名表格单元格元素(display 值为 table、table-row、 table-row-group、table-header-group、 table-footer-group(分别是 HTML table、tr、tbody、thead、tfoot 的默认值)或 inline-table)
  • overflow 值不为 visible、clip 的块元素。overflow 的默认值是 visible。
  • display 值为 flow-root 的元素。flow-root 可以创建一个无副作用的 BFC,就像 html 根元素那样。但需注意 flow-root 的兼容性, 它是一个较新的属性,IE 全系列不支持,Chrome58,Firefox53,Edge79开始支持。
  • contain 值为 layout、content 或 paint 的元素
  • 弹性元素(display 值为 flex 或 inline-flex 元素的直接子元素),如果它们本身既不是flex、grid也不是table容器
  • 网格元素(display 值为 grid 或 inline-grid 元素的直接子元素),如果它们本身既不是flex、grid也不是table容器
  • 多列容器(column-count 或 column-width 值不为 auto,包括column-count 为 1)
  • column-span 值为 all 的元素始终会创建一个新的 BFC,即使该元素没有包裹在一个多列容器中。

BFC 是什么?

关于 BFC 的概念,developer.mozilla 上这样解释

块格式化上下文(Block Formatting Context,BFC) 是 Web 页面的可视 CSS 渲染的一部分, 是块级盒子的布局过程发生的区域,也是浮动元素与其他元素交互的区域。

我的理解:

BFC 是一套渲染规则,是页面上一个独立的渲染区域,这个区域具有“独立隔离性”的特点。 “独立”和“隔离”是指对 BFC 区域内的布局改变,不会影响区域外部的布局,反之亦然。

拓展,其他 FC

FC 的全称是 Formatting Context,翻译过来就是格式化上下文,FC 种类有:

  • BFC(Block Formatting Context)块级格式化上下文

  • IFC(Inline Formatting Context)行内级格式化上下文

  • GFC(Grid Formatting Context)栅格格式化上下文

  • FFC(Flex Formatting Context)弹性格式化上下文

tips:CSS2.1 中只有 BFC 和 IFC,CSS3 中才有 GFC 和 FFC。