知乎文章地址:https://zhuanlan.zhihu.com/p/50478999

一. BFC的基本概念

BFC是“Block Formatting Context”的缩写,即块格式化上下文。它是Web页面的可视化CSS渲染的一部分,是布局过程中生成块级盒子的区域,也是浮动元素与其他元素的交互限定区域。通俗的讲,BFC是web页面中一块渲染区域(或者说是一种渲染环境),对于环境内的盒子,有某些特定的渲染规则。

再通俗的讲,就是我们可以为某一个盒子赋予BFC渲染环境,盒子内的子盒子在这个渲染环境中进行渲染。

二. 如何构建BFC

下列方式会构建块格式化上下文:(摘自:块格式化上下文

  • 根元素或包含根元素的元素
  • 浮动元素(元素的 float 不是 none
  • 绝对定位元素(元素的 position 为 absolute 或 fixed
  • 行内块元素(元素的 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、row、tbody、thead、tfoot的默认属性)或 inline-table
  • overflow 值不为 visible 的块元素
  • display 值为 flow-root 的元素
  • contain 值为 layoutcontent或 strict 的元素
  • 弹性元素(display为 flex 或 inline-flex元素的直接子元素)
  • 网格元素(display为 grid 或 inline-grid 元素的直接子元素)
  • 多列容器(元素的 column-count 或 column-width 不为 auto,包括 column-count 为 1
  • column-span 为 all 的元素始终会创建一个新的BFC,即使该元素没有包裹在一个多列容器中

三. BFC的一些特性(布局规则)

  1. 内部的Box(当然是块级盒子)会在垂直方向上沿边框一个接一个地放置;
  2. Box垂直方向上的margin由Box本身的margin决定,不是简单的两个相邻Box(同属同一个BFC中)的margin之和,而是取其中较大的那个margin,也就是所谓的Margin Collapse(margin重叠);
  3. BFC内部float box不会和同级的BFC区域重叠;
  4. BFC是页面上一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也是如此;
  5. 计算BFC的高度时,浮动元素也参与计算;

四. BFC的应用场景

1.Margin Collapse

首先,我们先看一个栗子:

  <div class="container">
    <p>Sibling 1</p>
    <p>Sibling 2</p>
  </div>

css如下:

    .container {
      background-color: red;
      /* create BFC box */
      overflow: hidden;
      text-align: center;
    }

    p {
      background-color: lightgreen;
      margin: 10px 0;
    }

效果如下:

深入理解BFC

这种效果也就是上面BFC特性中第二条所造成的。

同样的,我们也可以通过BFC来避免margin的一个折叠效果,即利用BFC的第四条特性,我们只要通过BFC与相邻的margin隔离开就行了,代码如下:

  <div class="container">
    <p>Sibling 1</p>
    <p>Sibling 2</p>
    <div class="newBFC">
      <p>Sibling 3</p>
    </div>
  </div>

 

    .container {
      background-color: red;
      overflow: hidden;
      text-align: center;
    }

    p {
      background-color: lightgreen;
      margin: 10px 0;
    }

    .newBFC {
      overflow: hidden;
    }

接着效果就是这样的:

深入理解BFC

2. 通过BFC来包含浮动

一个BFC可以包含浮动。很多时候我们会碰到这种情况,一个容器里有浮动元素。由于这个原因,容器元素没有高度(常被理解为元素浮动导致父容器坍塌),它的浮动孩子将会脱离页面的常规流。我们通常使用清除浮动来解决这个问题,最受欢迎的方法是使用一个clearfix的伪类元素。但我们同样可以通过定义一个BFC来达到这个目的。著作权归作者所有。

深入理解BFC

先看一个栗子:

深入理解BFC

代码如下:

  <div class="container">
    <div class="box"></div>
  </div>

css如下:

    .container {
      padding: 10px;
      background-color: green;
    }

    .box {
      width: 100px;
      height: 100px;
      border-radius: 5px;
      background-color: lightgreen;
      float: left;
    }

上面子元素因为浮动脱离了父元素的包裹,为了使得父元素能够将子元素进行包裹,我们将父元素设置成BFC即可(利用的是特性里的第五条):

    .container {
      overflow: hidden;
      padding: 10px;
      background-color: green;
    }

    .box {
      width: 100px;
      height: 100px;
      border-radius: 5px;
      background-color: lightgreen;
      float: left;
    }

效果如下:

深入理解BFC

可以看到,浮动元素已经被包裹住了。

3. 使用BFC来防止文字环绕

首先了解一下,文字环绕是什么?举个栗子:

深入理解BFC

这就是文字环绕,并且图中的浅绿色box是一个浮动元素,也正是这个浮动元素,导致了文本的一个环绕效果。

为了能够消除文字环绕的这种效果,同样可以使用BFC来解决这个问题,利用我们上面提到的第三条特性就可以解决,栗如:

  <div class="container">
    <div class="box"></div>
    <p>I am yaodebian. I am yaodebian. I am yaodebian. I am yaodebian. I am yaodebian. I am yaodebian. I am yaodebian. I am yaodebian. I am yaodebian. I am yaodebian. I am yaodebian. I am yaodebian. I am yaodebian. I am yaodebian. I am yaodebian. I am yaodebian. I am yaodebian. I am yaodebian. I am yaodebian. I am yaodebian. I am yaodebian. </p>
  </div>

css:

    .container {
      overflow: hidden;
      padding: 10px;
      background-color: green;
    }

    .box {
      width: 100px;
      height: 80px;
      border-radius: 5px;
      background-color: lightgreen;
      float: left;
    }

    p {
      overflow: hidden;
    }

上面通过为p标签设置overflow为hidden,以此为p构建一个BFC。

 

以上参考自以下几篇文章:

前端精选文摘:BFC 神奇背后的原理​www.cnblogs.com

理解CSS中BFC_CSS, BFC 教程_w3cplus​www.w3cplus.com

块格式化上下文​developer.mozilla.org

相关文章: