CSS中的BFC

122 阅读2分钟

什么是FC?

根据W3C官方文档:

Boxes in the normal flow belong to a formatting context, which may be block or inline, but not both simultaneously. Block-level boxes participate in a block formatting context. Inline-level boxes participate in an inline formatting context.

在标准流中的盒子属于一个格式化上下文(FC),它可能是块级元素或者行内级元素,但不都完全是。块级盒子参与BFC,行内级盒子参与IFC。也就是说FC就是一个格式块,格式块中的元素按标准流就行排布。

那什么是BFC呢?

官方文档的说明

Floats, absolutely positioned elements, block containers (such as inline-blocks, table-cells, and table-captions) that are not block boxes, and block boxes with 'overflow' other than 'visible' (except when that value has been propagated to the viewport) establish new block formatting contexts for their contents.

以下情况会创建BFC:

  • <HTML>元素
  • 使用float使其浮动的元素
  • 绝对定位的元素(position: absoluteposition:fixed
  • 使用display: inline-block
  • 表格单元格或使用 display: table-cell, 包括使用 display: table-* 属性的所有表格单元格
  • 表格标题或使用 display: table-caption 的元素
  • 块级元素的 overflow 属性不为 visible
  • 元素属性为 display: flow-root 或 display: flow-root list-item
  • 元素属性为 contain: layoutcontent, 或 strict
  • flex items
  • multicol containers
  • 元素属性 column-span

BFC的规则

根据官方文档中的9.410.6.7得出:

在同一个BFC的中

  • 元素按垂直方向进行排布,从包含块的顶部开始,垂直之间的距离margin会被合并
  • 所有元素的左侧外边缘会顶住包含块的左边(如果是从右到左的布局,那就是右边)
  • 如果只包含一个行内级的元素,那么高度就是行内级元素的高度
  • 如果包含多个块级元素,那么高度就是最顶部的元素的上边线和最底部的元素的下边线之间的距离
  • 绝对定位的元素会被忽略
  • 容器的底部就是最底部的浮动元素的下边线。

BFC的实际应用

解决折叠问题

案例一、

出现的问题:两个块级元素,希望在垂直方向上它们之间的距离为30px,但是在margin被合并了。两个元素的实际距离为20px,因为它们在同一个BFC中。

<!DOCTYPE html>
<html lang="en">
<head>
  <title>CSS Block Format Context</title>
  <style>
    .box1,
    .box2 {
      height: 200px;
      width: 200px;
    }

    .box1 {
      background-color: red;
      margin-bottom: 20px;
    }

    .box2 {
      background-color: blue;
      margin-top: 10px;
    }
  </style>
</head>

<body>
  <div class="box1"></div>
  <div class="box2"></div>
</body>
</html>

image.png

解决办法: 在两个块级元素中,给任意一个元素创建一个新的BFC环境,使它们不在同一个BFC中。

  <div style="overflow: hidden;">
    <div class="box1"></div>
  </div>
  <div class="box2"></div>

image.png

解决浮动元素高度塌陷问题

案例一、

出现的问题:因为浮动元素不会给父级元素汇报高度,所有父级元素的高度没有被撑起来。

<!DOCTYPE html>
<html lang="en">
<head>
  <title>Block Format Context</title>
  <style>
    .container {
      width: 500px;
      background-color: orange;
    }
    .box {
      float: left;
      width: 150px;
      height: 150px;
      margin: 10px;
      background-color: cornflowerblue;
    }
  </style>
</head>

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

image.png

解决办法: 只需要给.container元素添加一个overflow: hidden,使之成为一个新BFC,因为容器的底部就是最底部的浮动元素的下边线。

.container {
  width: 500px;
  background-color: orange;
  overflow: hidden;
}

image.png