2 BFC

块级格式化上下文,是一个独立的渲染区域,让处于 BFC 内部的元素与外部的元素相互隔离,使内外元素的定位不会相互影响。

IE下为 Layout,可通过 zoom:1 触发

触发条件:

  • 根元素,即HTML元素
  • 绝对定位元素 position: absolute/fixed
  • 行内块元素 display的值为inline-blocktableflexinline-flexgridinline-grid
  • 浮动元素:float值为leftright
  • overflow值不为 visible,为 autoscrollhidden

规则:

  1. 属于同一个 BFC 的两个相邻 Box 垂直排列
  2. 属于同一个 BFC 的两个相邻 Boxmargin 会发生重叠
  3. BFC 中子元素的 margin box 的左边, 与包含块 (BFC) border box的左边相接触 (子元素 absolute 除外)
  4. BFC 的区域不会与 float 的元素区域重叠
  5. 计算 BFC 的高度时,浮动子元素也参与计算
  6. 文字层不会被浮动层覆盖,环绕于周围

应用:

  • 利用2:阻止margin重叠
  • 利用4:自适应两栏布局
  • 利用 5 ,可以避免高度塌陷
  • 可以包含浮动元素 —— 清除内部浮动(清除浮动的原理是两个div都位于同一个 BFC 区域之中)

示例

1. 防止margin重叠(塌陷)

    <style>
        p {
          color: #f55;
          background: #fcc;
          width: 200px;
          line-height: 100px;
          text-align:center;
          margin: 100px;
        }
    </style>
    <body>
      <p>Haha</p >
      <p>Hehe</p >
    </body>

  • 两个p元素之间的距离为100px,发生了margin重叠(塌陷),以最大的为准,如果第一个Pmargin80的话,两个P之间的距离还是100,以最大的为准。
  • 同一个BFC的俩个相邻的盒子的margin会发生重叠
  • 可以在p外面包裹一层容器,并触发这个容器生成一个BFC,那么两个p就不属于同一个BFC,则不会出现margin重叠
    <style>
        .wrap {
            overflow: hidden;// 新的BFC
        }
        p {
            color: #f55;
            background: #fcc;
            width: 200px;
            line-height: 100px;
            text-align:center;
            margin: 100px;
        }
    </style>
    <body>
        <p>Haha</p >
        <div class="wrap">
            <p>Hehe</p >
        </div>
    </body>

这时候,边距则不会重叠:

2. 清除内部浮动

    <style>
        .par {
            border: 5px solid #fcc;
            width: 300px;
        }
     
        .child {
            border: 5px solid #f66;
            width:100px;
            height: 100px;
            float: left;
        }
    </style>
    <body>
        <div class="par">
          <div class="child"></div>
          <div class="child"></div>
        </div>
    </body>

BFC在计算高度时,浮动元素也会参与,所以我们可以触发.par元素生成BFC,则内部浮动元素计算高度时候也会计算

    .par {
        overflow: hidden;
    }

3. 自适应多栏布局

这里举个两栏的布局

    <style>
        body {
            width: 300px;
            position: relative;
        }
     
        .aside {
            width: 100px;
            height: 150px;
            float: left;
            background: #f66;
        }
     
        .main {
            height: 200px;
            background: #fcc;
        }
    </style>
    <body>
        <div class="aside"></div>
        <div class="main"></div>
    </body>

  • 每个元素的左外边距与包含块的左边界相接触
  • 因此,虽然.aslide为浮动元素,但是main的左边依然会与包含块的左边相接触,而BFC的区域不会与浮动盒子重叠
  • 所以我们可以通过触发main生成BFC,以此适应两栏布局
    .main {
      overflow: hidden;
    }

这时候,新的BFC不会与浮动的.aside元素重叠。因此会根据包含块的宽度,和.aside的宽度,自动变窄

Last Updated:
Contributors: leeguooooo