理解BFC

作者: 柏丘君 | 来源:发表于2017-08-02 11:52 被阅读0次

    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 代码:

    <div>
        <p></p>
        <p></p>
    </div>
    

    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阻止外边距叠加01.png
    2.设置元素的 overflow 属性
    HTML 代码:
    <div>
        <p></p>
    </div>
    <p></p>
    

    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阻止外边距叠加02.png

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

    <div>
        <p></p>
    </div>
    <p></p>
    

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

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

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

    <div>
        <p></p>
        <p></p>
    </div>
    

    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
    }
    

    展示效果:

    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;
    }
    

    运行效果:

    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;
    }
    

    运行效果:

    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;
    }
    

    运行效果:

    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;
    }
    

    运行效果:

    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

        本文链接:https://www.haomeiwen.com/subject/tddelxtx.html