三个案例搞懂BFC

741 阅读3分钟

BFC

1. 概念

这只是CSS布局知识中的一个普通概念,并不高深。

BFC的英文表达是Block Formatting Context,块格式化上下文。

首先要搞清楚什么是格式化上下文,Formatting Context(格式化上下文) 是 W3C CSS2.1 规范中的一个概念。它是页面中的一块渲染区域,并且有一套渲染规则,它决定了其子元素将如何定位,以及和其他元素的关系和相互作用,即它是页面上有一套渲染规则的渲染区域。

而BFC多了个B,这个B是块盒子,所以BFC是指页面上块盒子的渲染区域,它有自己的一套渲染规则。类似,也存在IFC这个概念,它是指行内格式化上下文(Inline formatting context),即行内盒子的渲染区域。

仅仅通过BFC的概念很难真正理解BFC,要结合BFC的特性和应用,但是首先要知道怎么创建BFC。

2. 触发BFC

常见的,满足以下任一一个条件即可创建BFC:

  1. 浮动元素(元素的 float 不是 none
  2. 绝对定位元素(元素的 positionabsolutefixed
  3. display为flexinline-blocktable-celltable-caption
  4. overflow 计算值(Computed)不为 visible 的块元素

此处没有一一列举,MDN上列举出了所有的创建方式

下面来看下BFC的特性和应用。

3. BFC的特性和应用

  1. BFC可以避免外边距合并
  2. BFC可以包含浮动的元素(清除浮动)
  3. BFC可以避免元素被浮动元素覆盖

下面一一举例说明

BFC避免外边距合并

当上下两个div,上边的div设置下外边距,下边的div设置上外边距时,两个外边距,会合并,取值为较大的外边距值,如图4-1所示。

vueresponse 图4-1

发生外边距合并的代码如下:

<body>
  <div class="top">上边的兄弟</div>
  <div class="bottom">下边兄弟</div>
</body>
  <style>
    div {
      width: 200px;
      height: 200px;
    }
    .top {
      background-color: red;
      margin-bottom: 100px;
    }
    .bottom {
      background-color: green;
      margin-top: 100px;
    }
  </style>

为了防止外边距的合并,可以将这两个div放在BFC容器中,代码如下:

  <div class="father">
    <div class="top">上铺的兄弟</div>
  </div>
  <div class="father">
    <div class="bottom">下铺兄弟</div>
  </div>
  <style>
    .father {
      overflow: auto; /*触发BFC*/
    }
    .top, .bottom {
      width: 200px;
      height: 200px;
    }
    .top {
      background-color: red;
      margin-bottom: 100px;
    }
    .bottom {
      background-color: green;
      margin-top: 100px;
    }
  </style>

设置后的结果如图4-2所示。

vueresponse 图4-2

BFC包含浮动的元素(清除浮动)

浮动的元素会脱离正常的文档流,造成父元素盒子的塌陷,如图4-3所示。

vueresponse 图4-4

发生父元素盒子塌陷的代码如下:

  <style>
    .father {
      border: 2px solid red;
    }
    .son {
      width: 200px;
      height: 200px;
      background-color: green;
      float: left;
    }
  </style>
<body>
  <div class="father">
    <div class="son"></div>
  </div>

触发容器的 BFC,那么容器将会包裹着浮动元素,解决父元素盒子的塌陷,代码如下:

设置后的结果,如图4-4所示。

vueresponse 图4-4

BFC避免元素被浮动元素覆盖

在同一个父级元素中,有左右两个元素,左边的元素浮动时,右边元素会跑到左边元素的位置,被左边的元素遮挡住,如图4-5所示。

vueresponse 图4-5

发生被浮动元素覆盖的代码如下:

  <style>
    .left {
      width: 200px;
      height: 200px;
      background-color: red;
      float: left;
    }
    .right {
      width: 300px;
      height: 300px;
      background-color: green;
    }
  </style>
<body>
  <div class="left">左边的兄弟</div>
  <div class="right">右边的兄弟</div>
</body>

此时,可触发右边元素的 BFC 特性,在右边元素的样式中加入 overflow: hidden,代码如下:

  <style>
    .left {
      width: 200px;
      height: 200px;
      background-color: red;
      float: left;
    }
    .right {
      width: 300px;
      height: 300px;
      background-color: green;
      overflow: hidden;
    }
  </style>
<body>
  <div class="left">左边的兄弟</div>
  <div class="right">右边的兄弟</div>
</body>

设置后的效果如下图4-6所示。

vueresponse 图4-6

4. 总结

从以上三个特性和应用上,可以看出,具有 BFC 特性的元素可以看作是隔离了的独立容器,容器里面的元素不会在布局上影响到外面的元素,并且 BFC 具有普通容器所没有的一些特性。

5. 参考

10 分钟理解 BFC 原理

快格式上下文