什么是块级格式化上下文(BFC)

281 阅读2分钟

什么是块级格式化上下文(BFC)?

BFC 是特殊的盒子,样式上和普通盒子没有什么区别,但是功能上是把 BFC 看作一个隔离的容器,里面的元素布局不会影响到外面的元素,BFC 盒子具有普通盒子不具备的特殊功能,如包含浮动元素和解决外边距塌陷等问题。

如何创建格式化上下文?

  1. 浮动元素(元素的float值不为none);
  2. 绝对定位元素(元素的position值为absolute或者fixed);
  3. overflow 值不为 visible 的元素;
  4. display 值为 flow-root 的元素;
  5. display 值为 inline-block,table-cell,table-caption,table、table-row、 table-row-group、table-header-group、table-footer-group,inline-table,inline-flex,inline-grid。

举个🌰

<!DOCTYPE html>
<html lang="en">
  <head>
    <style type="text/css">
      .red-outer {
        border: 1px solid #aaa;
        width: 300px;
      }
      .red-inner {
        float: left;
        border: 1px solid pink;
        padding: 20px;
      }
    </style>
  </head>
  <body>
    <div class="red-outer">
      <div class="red-inner">red inner</div>
    </div>
  </body>
</html>

<!DOCTYPE html>
<html lang="en">
  <head>
    <style type="text/css">
      .red-outer {
        border: 1px solid #aaa;
        width: 300px;
        overflow: hidden; /* 看这里 */
      }
      .red-inner {
        float: left;
        border: 1px solid pink;
        padding: 20px;
      }
    </style>
  </head>
  <body>
    <div class="red-outer">
      <div class="red-inner">red inner</div>
    </div>
  </body>
</html>

子元素设置为浮动元素之后,就跳出了父元素的包裹。这时候,我们设置父元素的 overflow 为 hidden ,在父元素中创建了格式化上下文,使得父元素能够正确地包裹子元素,达到我们想要的效果。不过这里最好做下代码注释,因为其他开发者可能不知道 overflow: hidden; 在这里的作用。你也可以尝试使用其他方法创建格式化上下文哦。

这里推荐使用 display: flow-root; 因为这个元素的这个值就是专为 BFC 设置的,没有其他副作用,而且可读性高。

BFC 还有另一个常见用处,就是解决外边距塌陷问题,我们一起来看一下。

1.父子元素的外边距塌陷问题

<!DOCTYPE html>
<html lang="en">
  <head>
    <style type="text/css">
      .red-outer {
        width: 300px;
        background: pink;
        /* overflow: hidden; */
      }
      .inner1,
      .inner2 {
        margin: 30px;
      }
    </style>
  </head>
  <body>
    <div class="red-outer">
      <div class="inner1">inner1</div>
      <div class="inner2">inner2</div>
    </div>
  </body>
</html>

父元素和子元素的上下边距之间发生了塌陷,使得 inner1 的上边距和 inner2 的下边距消失了。

解决方法是创建BFC

<!DOCTYPE html>
<html lang="en">
  <head>
    <style type="text/css">
      .red-outer {
        width: 300px;
        background: pink;
        overflow: hidden;
      }
      .inner1,
      .inner2 {
        margin: 30px;
      }
    </style>
  </head>
  <body>
    <div class="red-outer">
      <div class="inner1">inner1</div>
      <div class="inner2">inner2</div>
    </div>
  </body>
</html>

注意:外边距塌陷只会发生在上下边距,不会发生在左右边距。

2.同级元素的外边距塌陷问题

<!DOCTYPE html>
<html lang="en">
  <head>
    <style type="text/css">
      .red-outer {
        width: 300px;
        background: pink;
      }
      .inner1 {
        margin-bottom: 30px;
      }
      .inner2 {
        margin-top: 50px;
      }
    </style>
  </head>
  <body>
    <div class="red-outer">
      <div class="inner1">inner1</div>
      <div class="inner2">inner2</div>
    </div>
  </body>
</html>

因为同级别元素之间发生了外边距塌陷,所以 inner1 和 inner2 之间的边距只有50px,(发生外边距塌陷时,取大的值)

解决方法就是创建BFC

<!DOCTYPE html>
<html lang="en">
  <head>
    <style type="text/css">
     .red-outer {
        width: 300px;
        background: pink;
      }
      .inner1 {
        margin-bottom: 30px;
      }
      .inner2 {
        margin-top: 50px;
      }
    </style>
  </head>
  <body>
    <div class="red-outer">
      <div class="inner1">inner1</div>
      <div style="overflow: hidden">
        <div class="inner2">inner2</div>
      </div>
    </div>
  </body>
</html>

3.空元素的外边距塌陷问题

<html lang="en">
  <head>
    <style type="text/css">
      .red-outer {
        width: 300px;
      }
      .red-outer {
        width: 300px;
      }
      .inner1 {
        background: gray;
        height: 100px;
        margin-bottom: 5px;
      }
      .inner2 {
        background: yellow;
        margin-top: 20px;
        margin-bottom: 10px;
      }
      .inner3 {
        background: deepskyblue;
        margin-top: 15px;
        height: 100px;
      }
    </style>
  </head>
  <body>
    <div class="red-outer">
      <div class="inner1">inner1</div>
      <div class="inner2">inner2</div>
      <div class="inner3">inner3</div>
    </div>
  </body>
</html>

中间的空元素即没有设置高度的元素的外边距发生了塌陷,解决方法同样是用BFC。

<html lang="en">
  <head>
    <style type="text/css">
      .red-outer {
        width: 300px;
      }
      .red-outer {
        width: 300px;
      }
      .inner1 {
        background: gray;
        height: 100px;
        margin-bottom: 5px;
      }
      .inner2 {
        background: yellow;
        margin-top: 20px;
        margin-bottom: 10px;
      }
      .inner3 {
        background: deepskyblue;
        margin-top: 15px;
        height: 100px;
      }
    </style>
  </head>
  <body>
    <div class="red-outer">
      <div class="inner1">inner1</div>
      <div style="overflow: hidden">
        <div class="inner2">inner2</div>
      </div>
      <div class="inner3">inner3</div>
    </div>
  </body>
</html>

格式化上下文的意义?(为什么会有 BFC 的存在)

  1. 格式化上下文对浮动定位与清除浮动的意义重大。浮动定位和清除浮动都只能作用于同一个块级格式化上下文中的元素。浮动不会影响其它BFC中元素的布局,而清除浮动只能清除同一BFC中在它前面的元素的浮动。
  2. 解决外边距塌陷问题。