关于面试BFC的思考

307 阅读2分钟

两个重要概念Box和FC(Formatting Context)

Box

一个页面是由很多个 Box 组成的,元素的类型和 display 属性决定了这个 Box 的类型。不同类型的 Box,会参与不同的 Formatting Context。

FC(Formatting Context)

FC是W3C CSS2.1规范中的一个概念,定义的是页面中的一块渲染区域,并且有一套渲染规则,它决定了其子元素将如何定位,以及和其他元素的关系和相互作用。

BOX+FC

缩写含义

  • BFC:Block-Formatting-Context(块级格式化上下文)
  • IFC:Inline-Formatting-Context(行内格式化上下文)
  • FFC:Flex-Formatting-Context
  • GFC:Grid-Fomatting-Context

display属性说明

  • CSS2.1:BFCIFC
    • Block level的box会参与形成BFC,比如display值为blocklist-itemtable的元素。
    • Inline level的box会参与形成IFC,比如display值为inlineinline-tableinline-block
  • CSS3:增加了FFCGFC
    说明:FFCGFC都基于Block level的box或Inline level的box

BFC详解

BFC称为块级格式化上下文,是CSS中的一种渲染机制。是一个拥有独立渲染区域的盒子,规定了内部元素如何布局,并且盒子内部元素外部元素互不影响。

如何生成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 值为 flow-root 的元素
  • contain 值为 layout、content 或 paint 的元素
  • 弹性元素(display 为 flex 或 inline-flex 元素的直接子元素)
  • 网格元素(display 为 grid 或 inline-grid 元素的直接子元素)
  • 多列容器(元素的 column-count 或 column-width (en-US) 不为 auto,包括 column-count 为 1)
  • column-span 为 all 的元素始终会创建一个新的BFC,即使该元素没有包裹在一个多列容器中(标准变更,Chrome bug)。

BFC应用(解决的问题)

防止margin重叠

垂直方向的margin发生了重叠

<!DOCTYPE html>
<html lang="en">
  <style>
    * {
      margin: 0px;
    }
  </style>
  <body>
    <!-- BFC垂直方向边距重叠 -->
    <section id="margin">
      <style>
        #margin {
          background: yellow;
          overflow: hidden;
        }

        #margin div {
          margin: 25px auto 25px;
          height: 50px;
        }
        #div1 {
          background-color: pink;
        }
        #div2 {
          background-color: #f08200;
        }
        #div3 {
          background-color: green;
        }
      </style>
      <div id="div1">pink</div>
      <div id="div2">#f08200</div>
      <div id="div3">green</div>
    </section>
  </body>
</html>

image.png 说明:#f08200的margin-top、margin-buttom会和pink的margin-bottom、green的margin-top共享margin

解决方法
<!DOCTYPE html>
<html lang="en">
  <style>
    * {
      margin: 0px;
    }
  </style>
  <body>
    <!-- BFC垂直方向边距重叠 -->
    <section id="margin">
      <style>
        #margin {
          background: yellow;
          overflow: hidden;
        }
        #margin div {
          margin: 25px auto 25px;
          line-height: 50px;
        }
        #div1 {
          background-color: pink;
        }
        #div2 {
          overflow: hidden;
          background-color: #f08200;
        }
        #div3 {
          background-color: green;
        }
      </style>
      <div id="div1">pink</div>
      <!-- 通过 overflow: hidden解决 -->
      <div style="overflow: hidden;">
        <div id="div2">#f08200</div>
      </div>
      <div id="div3">green</div>
    </section>
  </body>
</html>

image.png

水平方向的margin发生了重叠

<!DOCTYPE html>
<html>
  <head>
    <style>
      * {
        margin: 0px;
      }
      body {
        writing-mode: vertical-lr;
      }

      div {
        height: 100px;
        width: 100px;
      }
      #green {
        margin: 25px;
        background-color: green;
      }
      #blue {
        margin: 25px;
        background-color: blue;
        /* display: inline-block; */
      }
      #red {
        margin: 25px;
        background-color: red;
      }
    </style>
  </head>
  <body>
    <div id="green"></div>
    <div id="blue"></div>
    <div id="red"></div>
  </body>
</html>

image.png

解决方法上段代码注释展开

image.png

其它参考我这篇文章

BFC

参考文章

BFC与IFC概念理解+布局规则+形成方法+用处