BFC(Block Formatting Context)块级格式化上下文之深层解读

1、BFC(Block Formatting Context)块级格式化上下文

注意:BFC首先是块,其次须要具有下面的条件之一才能够(通俗来讲,BFC就比如一所985或者211的高校,想要成为985或者211的高校,它是有前提条件的,首先他得是一所大学,不能拿一个小学来讲,就比如BFC得先是块,下一步才能是BFC;当知足了前提条件,再须要具有其余的条件才能够。)css

在正式说BFC具体内容以前,先说一下BoxFormatting Context是个什么东西:html

  • Box浏览器

    你们应该都不陌生,Box是CSS布局的对象和基本单位,直观点说就是一个页面是由不少个Box组成的。不一样类型的Box,会参与不一样的Formatting Context(一个决定如何渲染文档的容器),所以Box内的元素会以不一样的方式来渲染。markdown

    常见盒子类型:布局

    • block-level boxdisplay 属性为block, list-item, table 的元素,会生成block-level box。而且参与block fomatting context
    • inline-level boxdisplay 属性为 inline, inline-block, inline-table 的元素,会生成inline-level box。而且参与inline fomatting context
    • run-in box:CSS3中新增的,是一个块/行内元素混合,可使某些块级元素成为下一个元素的行内部分,目前不多有浏览器支持该元素。
  • Formatting contextflex

    Formatting context 是 W3C CSS2.1 规范中的一个概念。它是页面中的一块渲染区域,而且有一套渲染规则,它决定了其子元素将如何定位,以及和其余元素的关系和相互做用。spa

    常见的Formatting context3d

    • Block Formatting Context(简称BFC
    • Inline Formatting Context(简称IFC
    • CSS2.1 中只有 BFCIFC , CSS3中还增长了 GFCFFC

BFC(Block formatting context)直译为“块级格式化上下文”。它是一个独立的渲染区域,只有Block-level box参与建立BFC, 它规定了内部的Block-level Box如何布局,而且与这个独立盒子里的布局不受外部影响,固然也不会影响到外面的元素。code

2、BFC的触发条件:

  1. 根元素 (当前文档中 html 标签就是一个BFC);
  2. float 的值不为 none 的其余属性值;
  3. overflow 的值不为 visible的其余属性值(有 hiddenautoscroll);
  4. display 的值为 inline-block / table-cell / table-caption / flex / inline-flex
  5. position 的值为 absolutefixed

3、BFC的特性(优势)以及应用场景

一、box垂直方向的距离由 margin 决定,属于同一个 BFC 的两个相邻boxmargin会发生重叠

应用场景:能够解释为何margin上下会重叠,以及解决方法的缘由orm

  • 问题分析:默认状况下,两个相邻的boxmargin会发生重叠的缘由,是由于box1和box2都属于html,而htmlBFC。由于BFC里面规定了,属于同一个BFC的两个相邻boxmargin会发生重叠,因此box1和box2重叠了,也就是外边距重叠。

    默认状况下,两个相邻的box的margin会发生重叠:

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title></title>
            <style type="text/css"> body{margin: 0;padding: 0;} .box1{width: 300px;height: 300px;background: red;margin-bottom: 50px;} .box2{width: 400px;height: 400px;background: yellow;margin-top: 100px;} </style>
        </head>
        <body>
            <div class="box1"></div>
            <div class="box2"></div>	
        </body>
    </html>
    复制代码

    如图所示: 两个相邻的box的margin会发生重叠 两个相邻的box的margin会发生重叠

  • 解决方案:

    • 重叠以后,想要不重叠,能够给后面的元素添加一个父元素而且添加声明overflow: hidden; 来解决(添加其余声明也能够,只要能够触发BFC便可)
    • 能够解决的缘由是由于,当给box2添加了父元素而且添加了overflow:hidden;以后,这个父元素boxs就是BFC了,当前的结构里面box1属于BFC html,box2属于BFC boxs,这个时候box1和box2就不属于同一个BFC了,那么也就不会发生重叠了。

    具体代码以下:

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title></title>
            <style type="text/css"> body{margin: 0;padding: 0;} .box1{width: 300px;height: 300px;background: red;margin-bottom: 50px;} .box2{width: 400px;height: 400px;background: yellow;margin-top: 100px;} .boxs{overflow: hidden;} </style>
        </head>
        <body>
            <div class="box1"></div>
            <div class="boxs">
                <div class="box2"></div>
            </div>
        </body>
    </html>
    复制代码

    如图所示:实现效果(给box2添加父元素并声明触发BFC便可解决) 解决两个相邻的box的margin重叠

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

应用场景:能够解释为何高度塌陷能够用 overflow:hidden等方法解决

  • 问题分析:为何添加了 overflow:hidden;就能够解决高度塌陷,是由于添加了以后,就触发ulBFC,而BFC里面规定了,计算BFC高度的时候,浮动元素也参与计算。

    ul未触发BFC时,li浮动时,ul高度塌陷:

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title></title>
            <style type="text/css"> body,ul{margin: 0;padding: 0;} ul{border: 3px solid red;} ul li{float: left;list-style: none;border: 1px solid yellow;} </style>
        </head>
        <body>
             <ul>
             <li>浮动元素</li>
             <li>浮动元素</li>
             <li>浮动元素</li>
             <li>浮动元素</li>
             </ul>
        </body>
    </html>
    复制代码

    如图所示:

    当给ul添加了overflow:hidden;以后,就触发了ulBFC,而计算BFC高度的时候,浮动元素也参与计算:

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title></title>
            <style type="text/css"> body{margin: 0;padding: 0;} ul{border: 3px solid red;overflow: hidden;} ul li{float: left;list-style: none;border: 1px solid yellow;} </style>
        </head>
        <body>
             <ul>
             <li>浮动元素</li>
             <li>浮动元素</li>
             <li>浮动元素</li>
             <li>浮动元素</li>
             </ul>
        </body>
    </html>
    复制代码

    如图所示:

    overflow:auto/scroll或者display:flex/inline-flex/table等,均可以解决高度塌陷,也是由于触发了ulBFC

三、BFC的区域不会与float box发生重叠

应用场景:自适应两栏布局或者三栏布局

  • 问题分析:

    • 上面的一个元素浮动,下面的一个元素没有浮动,那么会发生重叠,缘由是由于浮动以后不占据位置,因此后面的元素会上去;
    • 当给下面的元素添加了floatoverflowdisplay的时候就不重叠了,缘由是由于给了这些声明以后,就触发了下面的元素为BFC,而BFC里面规定了,BFC区域不会与浮动盒子发生重叠。
    • 若是既要BFC区域不会与float box发生重叠,又要右边的容器自适应:
      • float 不能够;
      • overflowhiddenautoscroll;能够;
      • displayflexinline-flex;能够。

    当上面元素设置浮动,下面元素没有浮动,那么就会发生重叠:

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title></title>
            <style type="text/css"> .left {width: 300px;height: 300px;background: red;float: left;} .right {height: 400px;background: yellow;} </style>
        </head>
        <body>
            <div class="left">left</div>
            <div class="right">right</div>
        </body>
    </html>
    复制代码

    如图所示:

    当下面元素添加声明,触发BFC,就不会与浮动盒子发生重叠:

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title></title>
            <style type="text/css"> .left {width: 300px;height: 300px;background: red;float: left;} .right {height: 400px;background: yellow;overflow: hidden;} </style>
        </head>
        <body>
            <div class="left">left</div>
            <div class="right">right</div>
        </body>
    </html>
    复制代码

    如图所示:

  • 应用案例

    • 自适应两栏布局
    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title></title>
            <style type="text/css"> body,ul,ol{ margin: 0; padding: 0;} html,body{height: 100%;} .left{width: 300px;height:500px;background: #0000FF;float: left;} .right{height: 600px;background: yellow;overflow: hidden;} </style>
        </head>
        <body>
            <div class="left">left固定</div>
            <div class="right">right自适应</div>
        </body>
    </html>
    复制代码

    实现效果如图所示: 自适应两栏布局

    能够实现右侧自适应的方法属性有: overflow: hidden、auto、scroll; display: flex、inline-flex;

    • 三栏布局
    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title></title>
            <style type="text/css"> body{ margin: 0; padding: 0;} html,body{height: 100%;} .left{ width: 100px;height: 200px;background: red;float: left; } .center{ height: 400px;background: #00FFFF;overflow: hidden;margin-right: 200px; } .right{ width: 200px;height: 300px;background: #008000;float: left;position: absolute;top: 0;right: 0; } </style>
        </head>
        <body>
            <div class="left">left</div>
            <div class="center">center</div>
            <div class="right">right</div>
        </body>
    </html>
    复制代码

    实现效果如图所示: 三栏布局

    不一样分辨率下左右两侧内容固定不变,中间内容自适应(下面由于图片放大了因此左右两侧显得变大了,实际上并无改变大小): 三栏布局


在BFC中,最重要的就是上面三组特性,每一个特性的应用场景都是很是普遍的,在现实开发过程当中,也会常常用到。至于下面的三个特性就简单了解一下就能够了。


四、BFC内部的Box会在垂直方向,一个接一个的放置。

五、每一个元素的margin box的左边会与包含块border box的左边相接触(对于从左到右的格式化,不然相反),即便存在浮动也会如此。

六、BFC就是页面上的一个独立容器,容器里面的元素不会影响到外面的元素。


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

相关文章
相关标签/搜索