K162

Starwalker, Stardust.

0%

CSS 浮动:BFC 规范和清除浮动

关于 BFC

根据 Mozilla 的 MDN 文档1中关于 BFC(Box Formatting Content,块级格式化上下文)的说明:

A block formatting context is a part of a visual CSS rendering of a web page. It’s the region in which the layout of block boxes occurs and in which floats interact with other elements.

Formatting contexts affect layout, but typically, we create a new block formatting context for the positioning and clearing floats rather than changing the layout, because an element that establishes a new block formatting context will:

  • contain internal floats.
  • exclude external floats.
  • suppress margin collapsing.

讲简单点,BFC 是页面上的一个独立容器,内部的元素不会影响外部的元素,反之亦然。

而盒子是否形成 BFC,对元素的 CSS 浮动有重要影响。同时,BFC 还能取消 margin 塌陷(margin collapsing),以及阻止元素被 float 的元素覆盖。

举个栗子

一个没有形成 BFC 的例子:

1
2
3
4
5
6
<div>	<!-- 没有设置 height -->
<p></p>
<p></p>
</div>

<!-- p 标签设置了 height 和 float -->

如果一个父元素(例子中的 div 标签)不设置 height,而内部的子元素都为 float 时,就无法撑起自身:

noBFC

创建 BFC

创建 BFC 的方法有很多,从文档的根元素 <html> 标签,到设置 column-span: all; ,具体可参考 Mozilla 的 MDN 文档1中的详细描述。

但是,针对上述例子中的场景,创建 BFC 有 4 种典型的方法:

  1. 父元素 添加属性 overflow: hidden; (推荐)
  2. 父元素 position 属性的值不是 staticrelative (推荐)
  3. 父元素 float 属性的值不是 none
  4. 父元素 display 的值是 inline-block, flexinline-flex

效果如下:

BFC

清除浮动

浮动一定要封闭到一个盒子中,否则会对页面其他元素产生影响。

举个栗子

一个没有清除浮动的例子:

1
2
3
4
5
6
7
8
9
10
<div>
<p></p>
<p></p>
</div>
<div>
<p></p>
<p></p>
</div>

<!-- p 标签设置了 float -->

原因就在于 div 没有形成 BFC,导致子元素无法形成两行:

noClear

清除浮动的方法

如果父元素的高度固定,那么直接设置 height 属性即可。

但是,父元素高度如果不固定(如,元素内容是动态的),那么就不能设置固定的 height 值。此时,也有几个典型的方法:

1. 父元素形成 BFC

让父元素形成 BFC,如:设置 overflow: hidden;

2. 设置 clear:both; 属性

后面的父元素设置 clear:both;clear 属性用来清除浮动对自己的影响,both 参数表示左右浮动都清除。

但由于前面的父元素依旧没有 height,可能会在后续元素定位上产生些问题。

3. 使用 ::after 伪元素(推荐)

使用 ::after 伪元素,给父元素最后添加一个子元素,并且给 ::after 设置 clear:both

1
2
3
4
5
.clearfix::after {
content: '';
clear: both;
display: block; /* 别忘记设置 */
}

效果如下:

Clear

参考资料

[1] MDN contributors, Block formatting context