BFC到底是什么?

124 阅读4分钟

BFC到底是什么?

1.在了解BFC前,我们先聊聊FC,

FC的全称是Formatting Context(格式化上下文),以下是官方文档对FC的解释 1714031058496.png 简单总结:元素在标准流里面都是属于一个FC,它可能是一个Block Formatting Context(BFC)或者Inline Formatting Context(IFC),但是只能是其中之一。块级元素的布局属于BFC, 行内级元素的布局属于IFC

2.BFC有什么作用?

我们来看一下官方文档对BFC作用的描述 1714031834429.png 简单概况如下:

  • 在BFC中,box(块级元素)会在垂直方向上一个挨着一个的排布
  • 垂直方向的间距由margin属性决定
  • 在同一个BFC中,相邻两个box(块级元素)之间的margin会折叠(collapse)
  • 在BFC中,每个元素的左边缘是紧挨着包含块的左边缘的

3.BFC的高度是auto的情况下,是如下方法计算高度的?

首先我们看一下官方文档的解释 1714035285240.png 简单总结一下:

  • 如果只有inline-level,是行高的顶部和底部的距离
  • 如果有block-level,是由最底层的块上边缘和最底层块盒子的下边缘之间的距离
  • 如果有绝对定位元素,将被忽略
  • 如果有浮动元素,那么会增加高度以包括这些浮动元素的下边缘

4.什么情况下会创建BFC?

  • 根元素(HTML)
  • 浮动元素(元素的 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 计算值(Computed)不为 visible 的块元素
  • 弹性元素(display 为 flex 或 inline-flex 元素的直接子元素)
  • 网格元素(display 为 grid 或 inline-grid 元素的直接子元素)
  • display 值为 flow-root 的元素

5.BFC的实际应用

5.1解决margin的折叠问题

在上面提到,在同一个BFC中,相邻两个box(块级元素)之间的margin会折叠

我们通过代码来演示一下:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
       body {
        padding: 0;
        margin: 0;
        background-color: #ccc;
      }
      .box1 {
        background-color: skyblue;
      }
      .box1 .box1-child {
        height: 200px;
        width: 500px;
        background-color: purple;
        margin-bottom: 20px;
      }
      .box2 {
        height: 200px;
        background-color: orange;
        margin-top: 30px;
      }
    </style>
  </head>
  <body>
    <div class="box1">
      <div class="box1-child"></div>
    </div>
    <div class="box2"></div>
  </body>
</html>

效果: 1714033195871.png 可以看到,box1-child元素和box2元素之间的margin为30px,因为他们都属于HTML创建的BFC环境中,margin发生了折叠

接下来看创建新的BFC会发生什么

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      body {
        padding: 0;
        margin: 0;
        background-color: #ccc;
      }
      .box1 {
        background-color: skyblue;
        overflow: auto;
      }
      .box1 .box1-child {
        height: 200px;
        width: 500px;
        background-color: purple;
        margin-bottom: 20px;
      }
      .box2 {
        height: 200px;
        background-color: orange;
        margin-top: 30px;
      }
    </style>
  </head>
  <body>
    <div class="box1">
      <div class="box1-child"></div>
    </div>
    <div class="box2"></div>
  </body>
</html>

创建新的BFC后的效果: 1714033220073.png 上面这段代码通过给box1元素设置overflow: auto,使得box1元素创建了一个新的BFC,此时box1-child元素属于box1创建的BFC环境中,与HTML创建的BFC不为同一个,所以此时box1-child元素设置的margin-bottom不会与box2元素设置的margin-top产生折叠,从而解决了margin折叠的问题

5.2解决浮动高度塌陷问题

众所周知,当子元素设置了浮动,则子元素不会向父元素汇报高度,如果此时父元素没有设置高度(高度为auto),则父元素会产生高度塌陷

我们通过代码来演示一下:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      body {
        padding: 0;
        margin: 0;
        background-color: #ccc;
      }
      .box {
        background-color: skyblue;
      }
      .box .item {
        float: left;
        width: 200px;
        height: 100px;
        background-color: purple;
        border: 1px solid #000;
      }
    </style>
  </head>
  <body>
    <div class="box">
      <div class="item"></div>
      <div class="item"></div>
      <div class="item"></div>
      <div class="item"></div>
    </div>
  </body>
</html>

效果: 1714034635972.png 此时,虽然我们给父元素(box)设置了背景颜色,但是由于他的子元素设置了浮动,不会汇报高度给他,导致他高度为0,所以并不能看见它的背景颜色

通过BFC解决浮动高度塌陷

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      body {
        padding: 0;
        margin: 0;
        background-color: #ccc;
      }
      .box {
        background-color: skyblue;
        overflow: auto;
      }
      .box .item {
        float: left;
        width: 200px;
        height: 100px;
        background-color: purple;
        border: 1px solid #000;
      }
    </style>
  </head>
  <body>
    <div class="box">
      <div class="item"></div>
      <div class="item"></div>
      <div class="item"></div>
      <div class="item"></div>
    </div>
  </body>
</html>

通过BFC解决浮动高度塌陷效果: 1714034867447.png 可以看到,我们给父元素(box)设置了overflow:auto后,box元素创建了新的BFC环境,通过上面第三点的第四条规则可以了解到,BFC环境中如果有浮动元素,那么会增加高度以包括这些浮动元素的下边缘,所以此时box元素有了高度,背景色也能显示出来了