0%

css-block-formatting-context

CSS Block Formatting Context (BFC)

CSS中的Block Formatting Context(简称BFC - 块级格式化上下文)是一个非常重要的概念,也是前端面试中常考的题目之一,今天我们来彻底学习一下BFC。

什么是BFC?

简单来说BFC是一个独立自治的渲染区域,BFC内的样式和BFC外的样式之间互相不影响。

哪些情况下会生成BFC?

以下情况下都会产生BFC:

  1. 文档根元素<html>结点
  2. 浮动定位元素 - CSS中指定的float值不是none
  3. 绝对定位元素 - CSS中指定的position值为absolutefixed
  4. CSS中overflow属性的值不是visibleclip的元素
    1. overflow: hidden
    2. overflow: auto
    3. overflow: scroll
    4. overflow: overlay
  5. CSS中contain属性值为如下取值的元素
    1. contain: layout
    2. contain: strict
    3. contain: content
  6. CSS中display属性值为以下取值的情况:
    1. display: flow-root
    2. display: table-cell
    3. display: table-caption
    4. display: flow-root
    5. display: flex
    6. display: inline-flex
    7. display: grid
    8. display: inline-grid

可见这个规则十分的复杂,我们不一定要死记硬背这个规则,只要掌握BFC的特性即可。

BFC元素的特性:

独立的渲染区域

这个很好理解,也是BFC最重要的特点,BFC内的元素样式不会影响BFC外的元素样式,反之亦然。

包含浮动元素

计算BFC的高度时,浮动元素也参与计算

阻止外边距折叠

BFC内的元素不会和BFC外的元素发生外边距折叠现象。这个特性其实是特性一的延伸。

阻止元素被浮动元素覆盖

BFC区域不会与浮动元素重叠。

BFC的应用场景

清除浮动

请看以下代码,父元素背景为红色,子元素背景绿色,但是渲染后父元素背景色没有出来,这是为什么呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Title</title>
<style>
.parent {
background-color: red;
}

.child {
float: left;
background-color: green;
}
</style>
</head>
<body>
<div class="parent">
<div class="child">我是浮动元素</div>
</div>
</body>
</html>

这是因为父元素内只有一个子元素,而且这个子元素是浮动的,浮动元素会脱离文档流,导致没有元素来撑起父元素,所以父元素的高度为0,这就是所谓的高度塌陷(CSS中还有Border collapse, Margin collapse,感兴趣的可以一读),这是浮动布局中常见的一个问题。解决办法是给父元素添加overflow: hidden,这样父元素就会生成一个BFC,而BFC元素计算高度时是包含内部的浮动元素的,所以父元素的高度就会被撑开。

1
2
3
4
.parent {
background-color: red;
overflow: hidden; /* 生成BFC */
}

还有一种办法是使用伪元素,这个是比较传统的解决方式了,用完浮动之后及时清除是一个好习惯。

1
2
3
4
5
.parent::after {
content: "";
display: block;
clear: both;
}

阻止外边距折叠

请参考CSS外边距折叠

一个问题

float元素和绝对定位元素都会脱离文档流,那么他们会脱离所在的BFC吗?这个问题是我突然想到的,总结如下:

特性 浮动(float) 绝对定位(absolute/fixed)
脱离常规文档流
脱离所在BFC
影响BFC内部布局 是(文字环绕)
参与BFC高度计算
定位参照物 BFC内 最近的定位祖先
典型用途 文字环绕/传统布局 精确控制位置/叠加元素

由这个表格可知,float元素还是受BFC控制的,而绝对定位元素则不受BFC控制,绝对定位元素会脱离所在的BFC,直接定位到最近的定位祖先元素上。绝对定位元素可真是CSS中的异类呀。