Skip to content

什么是 BFC,IFC,GFC,FFC

Box 是 CSS 布局的对象和基本单位,一个页面由很多 Box 组成。

Box 的类型由元素的类型和 display 的属性决定,不同类型的 Box,有其不同的 Formatting Context。

在普通流中的盒子会参与一种格式化上下文,这个盒子可能是块盒或者行盒,但不可能同时是块盒又是行盒,块盒参与 BFC 行盒参与 IFC

Box 类型种类

  1. block-level box : display 为 block,list-item,table 的元素,会生成 block-level box,并参与 Block Formatting Context。

  2. inline-level box: display 为 inline,inline-block,inline-table 的元素,会生成 inline-level box.并参与 Inline Formatting Context。

  3. grid-level box : display : grid

  4. flex-level box : display : flex | inline-flex

BFC (block Formatting Context 块级格式化上下文),规定了内部的 Block-level Box 如何布局。

布局规则:

  1. 内部的 Box 会在垂直方向,一个接一个的放置。

  2. Box 垂直方向的距离由 margin 决定,属于同一个 BFC 的两个相邻 Box 的 margin 会重叠。

  3. 每个元素的 margin box 的左边,与包含块 border box 的左边相接触。即使浮动元素也是

  4. BFC 的区域不会与 float box 重叠

  5. BFC 就是页面上的一个隔离的独立容器,容器内的子元素不会影响到外面的元素。反之也如此。

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

哪些元素产生 BFC:

  1. 根元素

  2. float 属性不是 none

  3. position:absolute | fixed

  4. display : inline-block | table-cell | table-caption | flex | inline-flex

  5. overflow 不是 visible

效果

2. Box 垂直方向的距离由 margin 决定,属于同一个 BFC 的两个相邻 Box 的 margin 会重叠。

html
<div class="row row1" style="display: block;height: 20px;width: 100%;background-color: blue;margin: 20px 0;"></div>
<div class="row row2">
	<div style="display: block;height: 20px;width: 100%;background-color: red; margin: 20px 0;"></div>
	<div style="display: block;height: 20px;width: 100%;background-color: green;margin: 20px 0;"></div>
</div>

效果如下:

margin重叠

可见 row2 与 row1 之间没有形成 BFC,那么其就属于同一个 BFC 的,那么 margin 就会形成穿透和重叠的情况。

html
<div class="row row1" style="display: block;height: 20px;width: 100%;background-color: blue;margin: 20px 0;"></div>
<div class="row row2" style="overflow:auto;margin-top:50px;">
	<div class="row2-1" style="display: block;height: 20px;width: 100%;background-color: red; margin: 20px 0;"></div>
	<div class="row2-2" style="display: block;height: 20px;width: 100%;background-color: green;margin: 20px 0;"></div>
</div>

效果如下:

margin重叠

这时候通过第五种方式将 row2 形成一个新的 BFC 盒子,那么这时候 row2-1 就跟 row1 不属于同一个 BFC 了,那么两个元素之间的 margin 就不会重叠;

这时候我们在修改一下代码

html
<div class="row" style="display: block;height: 20px;width: 100%;background-color: blue;margin: 20px 0;"></div>
<div class="row" style="overflow: auto;margin-top: 50px;">
	<div style="display: block;height: 20px;width: 100%;background-color: red; margin: 20px 0;"></div>
	<div style="display: block;height: 20px;width: 100%;background-color: green;margin: 20px 0;"></div>
</div>

3. 每个元素的左外边缘(margin-left), 与包含块的左边(contain box left)相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。除非这个元素自己形成了一个新的 BFC。

4. BFC 的区域不会与 float box 重叠。

我们首先看一下效果

html
<div class="row" style="display: inline-block;height: 50px;width: 100%;background-color: blue;margin: 20px 0;">
	<div class="float-1" style="float: left;width:100px;height: 30px;background-color: red;"></div>
	<div class="row1-2" style="color: #fff;font-size:14px;">
		asdasdasdabdfsabniasdn sadjfoisaasdasdabdfsabniasdn sadjfoisasdasdabdfsabniasdn sadjfoisasdasdabdfsabniasdn
		sadjfoisasdasdabdfsabniasdn sadjfoisasdasdabdfsabniasdn sadjfoisasdasdabdfsabniasdn sadjfoisasdasdabdfsabniasdn
		sadjfoisasdasdabdfsabniasdn sadjfoisasdasdabdfsabniasdn sadjfoisasdasdabdfsabniasdn sadjfoisasdasdabdfsabniasdn
		sadjfoisasdasdabdfsabniasdn sadjfoisj dfoi jasdoi jfoi j
	</div>
</div>

效果如下:

浮动

但是如果我们将 row1-2 变成浮动元素那?

html
<div class="row" style="display: inline-block;height: 50px;width: 100%;background-color: blue;margin: 20px 0;">
	<div class="float-1" style="float: left;width:100px;height: 30px;background-color: red;"></div>
	<div style="color: #fff;font-size:14px;overflow: auto;background-color: green;">
		asdasdasdabdfsabniasdn sadjfoisaasdasdabdfsabniasdn sadjfoisasdasdabdfsabniasdn sadjfoisasdasdabdfsabniasdn
		sadjfoisasdasdabdfsabniasdn sadjfoisasdasdabdfsabniasdn sadjfoisasdasdabdfsabniasdn sadjfoisasdasdabdfsabniasdn
		sadjfoisasdasdabdfsabniasdn sadjfoisasdasdabdfsabniasdn sadjfoisasdasdabdfsabniasdn sadjfoisasdasdabdfsabniasdn
		sadjfoisasdasdabdfsabniasdn sadjfoisj dfoi jasdoi jfoi j
	</div>
</div>

效果如下:

浮动

这就是 BFC 的第 4 条规则(BFC 的区域不会与 float box 重叠),所以 float-1 元素就不是浮动在元素 row1-2 上,而是并排排列

5. BFC 就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。

在我们讲解第一个 margin 重叠的时候,我们在 row2-1 与 row1 之间发生了 margin 的重叠,然后我们通过将 row2 变成 BFC 的方式 使得 row2-1 的 margin-top 与 row1 的 margin-bottom 之间不形成 margin 的重叠。 这也是 BFC 的布局规则 5:BFC 就是页面上的一个隔离独立的容器

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

这个就涉及到浮动元素高度坍塌的问题。如下面

html
<!-- 我们不把row设置成BFC元素 -->
<div class="row" style="width: 100%;height:10px;background-color: blue;margin: 20px 0;">
	<div class="float-1" style="float: left;width:100px;height: 30px;background-color: red;"></div>
</div>

效果如下:

高度坍塌

但是我们如果将 row 形成 BFC,那么根据布局规则 6,计算 BFC 内部的高度是,浮动元素也参与计算,那么这时候 row 的高度就不应该是 10px 而是 30px;

html
<div class="row" style="display: inline-block;width: 100%;background-color: blue;margin: 20px 0;">
	<div class="float-1" style="float: left;width:100px;height: 30px;background-color: red;"></div>
</div>

效果如下:

高度坍塌

作用

1. 自适应两栏布局

html
<div class="row" style="background-color: blue;">
	<div class="left" style="float: left;width: 100px;height: 100px;background-color: red;"></div>
	<div class="center" style="background-color: green;">
		asdasdsadfasdfsadfsaaaaaaaaaaa dasdsadfasdfsad 23 4213 4213 5213 45adfasdfsad 23 4213 4213 5213 45adfasdfsad 23 4213
		4213 5213 45adfasdfsad 23 4213 4213 5213 45adfasdfsad 23 4213 4213 5213 45
	</div>
</div>

自适应两栏布局

我们可以看到右边的元素被左边的元素遮挡起来,当然这时候我们可以设置 padding-left:100px去去除浮动元素遮挡的影响,但是这时候我们会发现几个问题:1. 浮动元素的宽度需要固定,不然padding-left不知道多大的值。 2. 浮动元素的背景色需要与右边元素背景色相同,不然会出现如图的左下方存在一段右边的背景色。这时候就可以通过将右边元素设置成BFC盒子。

html
<div class="row" style="background-color: blue;">
	<div class="left" style="float: left;width: 100px;height: 100px;background-color: red;"></div>
	<div class="center" style="background-color: green;overflow: auto;">
		asdasdsadfasdfsadfsaaaaaaaaaaa dasdsadfasdfsad 23 4213 4213 5213 45adfasdfsad 23 4213 4213 5213 45adfasdfsad 23 4213
		4213 5213 45adfasdfsad 23 4213 4213 5213 45adfasdfsad 23 4213 4213 5213 45
	</div>
</div>

自适应两栏布局

这是根据BFC布局规则的第4、5条,BFC区域是独立的不会与页面其他元素相互影响,且不会与float元素重叠,从而形成两栏自适应布局

2. 清除内部浮动

这个是很常见的一个问题,我们元素因为子元素是浮动元素,而导致高度坍塌的问题。如上面布局规则6所讲

高度坍塌

这时候将元素设置成BFC元素即(overflow: auto;)使其形成BFC,根据BFC规则第六条,计算高度时就会计算float的元素的高度,达到清除浮动影响的效果。

3. 防止垂直 margin 重叠

详细请看布局规则第二条