BFC入门

作者: 3ef698de5362 | 来源:发表于2018-11-15 21:01 被阅读0次

    BCF简介

    在一个Web页面的CSS渲染中,块级格式化上下文(Block Formatting Context)是按照块级盒子布局的。

    构成BFC的条件:

    下列条件满足任意一个或多个条件即可:

    1. float 的值不是none
    2. position的值不是static或者relative
    3. display的值是inline-block table-cell flex tabel-caption或者inline-flex
    4. overflow的值不是visible

    如何创建一个BFC

    要显示创建一个BFC非常简单,只要满足上述4个CSS条件之一即可。例如

    <div class="container">
          内容部分
    </div>
    

    在类container中添加类似overflow:scroll, overflow:hidden, display:flex, float:left规则来创建BFC,虽然都能创建,但是会有一些副作用:
    display:table 可能引发相应问题
    overflow:scroll 可能会显示多余滚动条
    float:left 将把元素移至左侧,并被其他元素环绕
    overflow:hidden 将裁剪溢出元素
    无论什么时候创建BFC都要基于自身需要来考虑。

    BCF补充

    1 BFC中盒子怎么对齐
    在一个BFC中,块盒和行盒(行盒由一行中所有内联元素构成)都会垂直的沿着其父元素的边框排列。
    在BFC中每一个盒子的左外边缘(margin-left)都会触碰到容器的左边缘(border-left)(对于从右到左的格式来说,则触碰到右边缘)。浮动也是如此(尽管盒子里的行盒子Line Box可能由于浮动而变窄),除非盒子创建了一个新的BFC(在这种情况下盒子本身有可能因为浮动而变窄)。



    2 外边距折叠
    常规流布局时,盒子都是垂直排列,两者之间间距各自由外边距所决定,但不是两者外边距之和

    <div class="container">
        <p>Sibling</p>
        <p>Sibling</p>
    </div>
    /*对应CSS*/
    .container {
        blackground-color:red;
        overflow:hidden; //创建一个BFC
    }
    p {
        backgound-color: lightgreen;
        margin:10px 0;
    } 
    

    渲染结果如上图所示
    理论上来讲,两个P元素之间的外边距应当是两者外边距之和(20px)但实际上却是10px,这是外边距折叠(Collapsing Margins)的结果。在CSS中,相邻的两个盒子(可能是兄弟关系也可能是祖先关系)的外边距可以结合成一个单独的外边距。这种合并边距的方式被称为折叠,并且因所结合成的外边距称为折叠外边距。折叠的结果按照如下规则计算:
    1)两个相邻的外边距都是正数时,折叠结果是他们两者之间较大的数值
    2)两个相邻的外边距都是负数时,折叠的结果是两者绝对值的较大值
    3)两个外边距一正一负,折叠结果是两者相加

    BFC可以做什么

    BFC可能造成外边距的折叠,也可以利用他来避免这种情况。BFC产生外边距折叠需要满足一个条件:两个相邻元素要处于同一个BFC中。若两个相邻元素不在同一个BFC中,就能避免外边距的折叠。

    /*改进前面的例子*/
    <div class="container">
        <p>Sibling 1</p>
        <p>Sibling 2</p>
        <p>Sibling 3</p>
    </div>
    对应CSS
    .container {
      background-color: red;
      overflow: hidden; /* creates a block formatting context */
    }
    p {
      background-color: lightgreen;
      margin: 10px 0;
    }
    /*结果和上面一样,由于外边距折叠,三个相邻P元素之间的垂直距离是10px,这是因为三个 p 标签都从属于同一个BFC。
    修改第三个P元素,使之创建一个新的BFC:*/
    <div class="container">
        <p>Sibling 1</p>
        <p>Sibling 2</p>
        <div class="newBFC">
            <p>Sibling 3</p>
        </div>
    </div>
    对应CSS
    .container {
        background-color: red;
        overflow: hidden; /* creates a block formatting context */
    }
    p {
        margin: 10px 0;
        background-color: lightgreen;
    }
    .newBFC {
        overflow: hidden;  /* creates new block formatting context */
    }
    

    现结果如下图所示



    因为第二个和第三个p元素不在同一个BFC中,他们之间就不会发生外边距折叠了。
    2 BFC包含浮动
    浮动元素是会脱离文档流的(绝对定位会脱离文档流).如果一个没有高度或者height是auto的容器的子元素都是浮动元素,则容器的高度是不会被撑开的。我们通常会使用为元素来解决这个问题。BFC能包含浮动,也能解决高度不会被撑开的问题。



    看个例子:
    <div class="container">
        <div>Sibling</div>
        <div>Sibling</div>
    </div>
    CSS:
    
    .container {
      background-color: green;
    }
    .container div {
      float: left;
      background-color: lightgreen;
      margin: 10px;
    }
    /*这这个例子中,容器没有任何高度,并且它包含不住浮动元素,容器的高度不会被撑开。
    为解决这个问题,可以在容器中创建一个BFC*/
    .container {
        overflow: hidden; /* creates block formatting context */
        background-color: green;
    }
    .container div {
        float: left;
        background-color: lightgreen;
        margin: 10px;
    }
    /*现在这个容器可以包住浮动子元素了,并且高度会扩展其包住子元素,
    在这个新的BFC中浮动元素又回归到页面的常规流之中了*/
    

    3 利用BFC避免文字环绕


    BFC5.jpeg

    如上图所示,对于浮动元素,可能会造成文字环绕的情况(Figure1),但这并不是我们想要的布局(Figure2才是想要的)。要解决这个问题,我们可以用外边距,但也可以用BFC。
    假设HTML是:

    <div class="container">
        <div class="floated">
            Floated div
        </div>
        <p>
            Quae hic ut ab perferendis sit quod architecto, 
            dolor debitis quam rem provident aspernatur tempora
            expedita.
        </p>
    </div>
    

    上图整个黑色区域表示 p 元素。p 元素没有移位但它叠在了浮动元素之下,而p元素的文本(行盒子)却移位了,行盒子水平变窄来给浮动元素腾出了空间。随着文本的增加,最后文本将环绕在浮动元素之下,因为那时候行盒子不再需要移位,也就成了图Figure1的样子。
    再回顾一下W3C的描述:
    在BFC上下文中,每个盒子的左外侧紧贴包含块的左侧(从右到左的格式里,则为盒子右外侧紧贴包含块右侧),甚至有浮动也是如此(尽管盒子里的行盒子 Line Box 可能由于浮动而变窄),除非盒子创建了一个新的BFC(在这种情况下盒子本身可能由于浮动而变窄)。
    因而,如果p元素创建一个新的BFC那它就不会再紧贴包含块的左侧了。
    在多列布局中使用BFC
    如果我们创建一个占满整个容器宽度的多列布局,在某些浏览器中最后一列有时候会掉到下一行。这可能是因为浏览器四舍五入了列宽从而所有列的总宽度会超出容器。但如果我们在多列布局中的最后一列里创建一个新的BFC,它将总是占据其他列先占位完毕后剩下的空间。
    例如:

    <div class="container">
        <div class="column">column 1</div>
        <div class="column">column 2</div>
        <div class="column">column 3</div>
    </div>
    对应的CSS:
    
    .column {
        width: 31.33%;
        background-color: green;
        float: left;
        margin: 0 1%;
    }
    /*  Establishing a new block formatting 
        context in the last column */
    .column:last-child {
        float: none;
    overflow: hidden; 
    }
    

    现在尽管盒子的宽度稍有改变,但布局不会打破。当然,对多列布局来说这不一定是个好办法,但能避免最后一列下掉。这个问题上弹性盒或许是个更好的解决方案,但这个办法可以用来说明元素在这些环境下的行为。

    相关文章

      网友评论

          本文标题:BFC入门

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