带你看懂 BFC

158 阅读3分钟

一、什么是BFC

W3C对BFC的定义如下: 浮动元素和绝对定位元素,非块级盒子的块级容器(例如 inline-blocks, table-cells, 和 table-captions),以及overflow值不为"visiable"的块级盒子,都会为他们的内容创建新的BFC(Block Formatting Context, 即块级格式上下文),它是一个独立的渲染区域,只有Block-level box参与, 它规定了内部的Block-level Box如何布局,并且与这个区域外部毫不相干。

  • 浮动元素 float
  • 绝对定位元素 position: absolute 或 fixed;
  • 非块级盒子的块级容器 inline-blocks, table-cells, 和 table-captions
  • overflow值 hidden scroll auto inherit ,不为visible

二、BFC 触发的方式

一个HTML元素要创建BFC,则满足下列的任意一个或多个条件即可:

  • 根元素,即HTML标签
  • 浮动元素 float 非 none
  • 绝对定位元素 position: absolute 或 fixed;
  • 行内块级元素 display: inline-blocks
  • 表格单元格 display: table-cells (HTML 表格单元格默认为该值)
  • 表格标题 display: table-captions(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为 flex 或 inline-flex元素的直接子元素
  • 网格元素 display为 grid 或 inline-grid 元素的直接子元素 等等

三、BFC 的渲染规则

  1. BFC 垂直方向边距重叠
  2. BFC 的区域不会与浮动元素的 box 重叠
  3. BFC 是一个独立的容器,外面的元素不会影响里面的元素
  4. 计算 BFC 高度时,浮动元素也会计算在内

四、BFC 的应用

1、高度塌陷,清除浮动

根据上述 BFC 渲染规则第四点很容易就能知道 BFC 可以用于解决浮动元素导致的高度塌陷问题

例如:

html

<div id="context">
    <div class="float"></div>
</div>

css

#context {
    width: 200px;
    border: 2px red solid;
}

.float {
    width: 100px;
    height: 100px;
    background-color: blue;
    float: left;
}

就会造成高度塌陷,导致如下效果:

将 context 触发BFC就能将浮动元素的高度也加入计算,从而撑起父盒子的高度,解决高度塌陷问题

如下,css 改为:

#context {
    width: 200px;
    border: 2px red solid;
    overflow: hidden; // 添加一句
}

.float {
    width: 100px;
    height: 100px;
    background-color: blue;
    float: left;
}

2、阻止垂直外边距折叠

属于同一个BFC的两个相邻块级子元素(元素都要在文档流中)的上下margin会发生重叠—— 分为两个BFC就可以消除这种margin 重叠

例如:

html

<div id="box">
    <div class="item"></div>
    <div class="item"></div>
</div>

css

#box {
    width: 300px;
    background-color: red;
    overflow: hidden;
}

.item {
    width: 100%;
    height: 50px;
    background-color: blue;
    margin: 20px 0;
}

效果如下:

在同一个BFC中的相邻两个块级元素垂直外边距折叠了,中间的红色空间隙本来应该是 20 + 20 的,结果只有 20,这个折叠是会选择边距大的吞并边距小的的,比如 40 + 20 的上下边距叠在一起就会变成 40。

那么如果要使这个垂直边距变回简单的加法,就需要将相邻的块级元素放在不同的 BFC 里面

例如:

html

<div id="box">
    <div class="item"></div>
    <div class="clr">
        <div class="item"></div>
    </div>
</div>

css

#box {
    width: 300px;
    background-color: red;
    overflow: hidden;
}

.item {
    width: 100%;
    height: 50px;
    background-color: blue;
    margin: 20px 0;
}

.clr {
    overflow: hidden; // 再套一个
}

效果:

就阻止了这种边距的重叠效果。