理解BFC

BFC 的全称是 Block Formating Context,译为“块级格式化上下文”,是 CSS 规范中的一个概念,规定了一套渲染规则,规定了内部的子元素如何布局,以及他们和其他元素的关系等。
除了 BFC 之外,规范中还有 IFC 的概念,也就是 Inline Formating Context,译为“内联格式化上下文”。
BFC 和 IFC 都是 CSS 2.1 中的规范,在 CSS3 中,还有 GFC、FFC 等。
本文的重点是对 BFC 的理解,理解了 BFC 之后,就对 CSS 中的很多东西有了原理化的认知,更加明白 CSS 中的一些难点特性,如浮动、定位等。

你要知道的

在学习 BFC 之前,你需要知道下面几个要点:

  • BFC 规定了浏览器对于元素和子元素渲染方式
  • BFC 是需要触发条件的
  • 只有触发了 BFC 的元素才能应用 BFC 的规则
  • BFC 元素和 display:block 的元素没有半毛钱关系

BFC 的一些特性

BFC 包含以下一些常用特性:

  • BFC 容器会阻止外边距叠加
  • BFC 容器会阻止其被浮动元素覆盖
  • 计算 BFC 容器的高度时,会包含浮动元素

这三个特性可以算是 BFC 中最常用的几个特性了,可以帮助我们理解浮动、清浮动等知识。

触发 BFC

满足下列任意条件,就可以触发 BFC:

  • float 设置为 none 以外的值(leftright
  • overflow 设置为 visible 以外的值(hiddenautoscroll
  • position 设置为 relative 以外的值(absolutefixed
  • display 设置为 inline-blocktabletable-celltable-caption

需要注意的是,display:table 本身并不会创建BFC,但是它会产生匿名框(anonymous boxes),而匿名框中的display:table-cell可以创建新的BFC,换句话说,触发块级格式化上下文的是匿名框,而不是display:table。所以通过display:table和display:table-cell创建的BFC效果是不一样的。

上面的文字引用于那些年我们一起清除过的浮动。

应用

了解了 BFC 的常用特性以及触发条件后,我们可以使用 HTML+CSS 来对这些理论进行验证。下面依次验证这几个特性:

BFC 容器会阻止外边距叠加

外边距叠加是在元素在垂直方向上margin值的叠加效应,我在这篇文章中也做了一些总结,您可以进行查看。
1.设置元素的 float 属性
HTML 代码:

CSS 代码:

div{
    height: 20em;
    border: .1em dashed #ccc;
}
p{
    margin: 0;
    width: 5em;
    height: 5em;
    background: red;
}
p:first-of-type{
    margin-bottom:5em ;
}
p:last-of-type{
    float: left;
    background: blue;
    margin-top: 5em;
}

效果如下:

理解BFC_第1张图片
BFC阻止外边距叠加01.png

2.设置元素的 overflow 属性
HTML 代码:

CSS 代码:

div{
    overflow: hidden;
}
p{
    margin: 0;
    width: 5em;
    height: 5em;
    margin-top: 5em;
    background: red;
}
div > p{
    margin-bottom:5em ;
    margin-top: 0;
    background: blue;
}

效果展示:

理解BFC_第2张图片
BFC阻止外边距叠加02.png

3.设置元素的 display 属性
HTML 代码:

CSS 代码:

div{
    display: table-cell;
}
p{
    margin: 0;
    width: 5em;
    height: 5em;
    margin-top: 5em;
    background: red;
}
div > p{
    margin-bottom:5em ;
    margin-top: 0;
    background: blue;
}

效果预览:

理解BFC_第3张图片
BFC阻止外边距叠加03.png

4.设置元素的 position 属性
使用绝对定位固定定位的元素脱离了标准文档流,并且有了层级的概念,因此其边距不会和其他元素的边距产生叠加效应(因为不在同一个层级),这个效果不好演示,这里就略过了~

BFC 容器会阻止其被浮动元素覆盖

我们知道浮动元素是一个 BFC 容器,其脱离了标准的文档流,其后面元素就好像这个元素不存在一样。浮动元素会一直想或者向右移动,直到其碰到了父级元素或者其他元素的边缘才停止。
先看一个简单的 Demo:
HTML 代码:

CSS 代码:

div{
    width: 20em;
    height: 5em;
    border: 1px dashed #ccc;
}
p{
    width: 5em;
    height: 5em;
    margin: 0;
}

div >p:first-of-type{
    background: red;
    float: left;
}

div >p:last-of-type{
    background: blue;
    width: 10em
}

展示效果:

理解BFC_第4张图片
BCF元素阻止浮动元素对齐覆盖01.png

可见,由于第一个段落采用了浮动,便脱离了标准文档流,其后面的元素就好像这个浮动元素不存在一样,直接挨着父级元素排列,所以视觉效果上,后面的那一个段落被覆盖掉了。
由于BFC 容器会阻止其被浮动元素覆盖,因此我们只需要让后面的段落触发 BFC 就可以阻止浮动元素的覆盖啦。
1.设置元素的 float 属性
CSS 代码:

div{
    width: 20em;
    height: 5em;
    border: 1px dashed #ccc;
}
p{
    width: 5em;
    height: 5em;
    margin: 0;
}

div >p:first-of-type{
    background: red;
    float: left;
}

div >p:last-of-type{
    background: blue;
    width: 10em;
    float: left;
}

运行效果:

理解BFC_第5张图片
BCF元素阻止浮动元素对齐覆盖02.png

2.设置元素的 overflow 属性
CSS 代码:

div{
    width: 20em;
    height: 5em;
    border: 1px dashed #ccc;
}
p{
    width: 5em;
    height: 5em;
    margin: 0;
}

div >p:first-of-type{
    background: red;
    float: left;
}

div >p:last-of-type{
    background: blue;
    width: 10em;
    overflow: hidden;
}

运行效果:

理解BFC_第6张图片
BCF元素阻止浮动元素对齐覆盖03.png

3.设置元素的 display 属性
CSS 代码:

div{
    width: 20em;
    height: 5em;
    border: 1px dashed #ccc;
}
p{
    width: 5em;
    height: 5em;
    margin: 0;
}

div >p:first-of-type{
    background: red;
    float: left;
}

div >p:last-of-type{
    background: blue;
    width: 10em;
    display: inline-block;
}

运行效果:

理解BFC_第7张图片
BCF元素阻止浮动元素对齐覆盖04.png

4.设置元素的 position 属性
CSS 代码:

div{
    width: 20em;
    height: 5em;
    border: 1px dashed #ccc;
}
p{
    width: 5em;
    height: 5em;
    margin: 0;
}

div >p:first-of-type{
    background: red;
    float: left;
}

div >p:last-of-type{
    background: blue;
    width: 10em;
    position: absolute;
}

运行效果:

理解BFC_第8张图片
BCF元素阻止浮动元素对齐覆盖04.png

这个最霸道,不仅阻止了浮动元素对其自身进行覆盖,反而还把浮动元素给覆盖了,666

计算 BFC 容器的高度时,会包含浮动元素

这也就是清除浮动的原理了,因为浮动会将元素的 inline-box 设置为0,而我们知道 containing-box 的高度本质上是由 inline-box 决定的(您可以参考这篇文章,里面进行了一些总结),所以如果一个元素中的元素都进行了浮动,那么这个完成元素的高度就塌陷了。为了解决这个问题,我们只需要“找回”外层元素的高度就可以了,运用到的就是 BFC 的这个特性:计算 BFC 容器的高度时,会包含浮动元素。
关于浮动这一块,里面又有很多概念,需要再用一片文章来写,这里就不再往下写了。后面会出一篇和浮动有关的文章,再进行说明。

总结

本文主要讲解了 BFC 的概念,BFC 是 CSS 2.1 中的一项规范,规定了其和子元素的一些呈现方式。BFC 需要一些触发条件,和浮动、定位、行内块等知识点关系紧密,需要我们去深入理解。

附:参考资料
那些年我们一起清除过的浮动
理解 BFC (Block Formatting Model)
CSS之BFC详解
深度理解现代浏览器中的BFC和IE下的haslayout

完。

你可能感兴趣的:(理解BFC)