bfc布局

作者: 刘松阳 | 来源:发表于2019-06-03 15:23 被阅读0次

    BFC(Block Formatting Contexts -- 块格式化布局)布局是需要其他属性值设置为某些特定的值方可触发BFC布局,也就是说这个bfc不像弹性布局一样,只要申明display:flex就可以申明一个flex的容器,bfc有一些特定的属性值,申明之后自动回触发bfc,能触发bfc布局的属性如下:

    float的属性值不是none。
    overflow的属性值不是visible
    position的值不是static和relative的
    display的值是table-cell,inline-block,table-caption中的一个;
    bfc布局决定了父元素(块级元素)如何对它的子元素(块元素)进行布局以及和其兄弟元素的相互作用。同时bfc布局可以看做是和外面隔离的一个单独的渲染区域,他有自己的渲染规则,不会影响到bfc区域外的元素,反之,区域之外的元素也不会影响bfc区域元素的布局。

    那bfc有哪些特性呢?或者说bfc有什么作用呢?下面从三个方面来描述bfc布局的特点:

    1:阻止外边距折叠的现象:

    这里先解释一下外边距折叠原则:块级元素的上下外边距(margin)在某些情况下会合并(折叠)起来,合并之后的大小为较大的margin。注意浮动和绝对定位的元素的margin从不折叠。
    

    准确的应该是说垂直外边距折叠,因为水平方向上是不会发生折叠的。

    哪些情况下会发生折叠呢。?或者说折叠外边距的条件是什么呢。?有两种情况,分别如下:

    a:垂直相邻的垂直元素;这个很好理解,也比较常见,不过需要注意的是,这儿的相邻是指渲染之后元素位置相邻,而不是说dom结构上的相邻,代码如下:           
    

    <style>
    .container{

        }
        .item{
            margin: 20px;
            width: 300px;
            height: 50px;
            border: 1px solid red;
        }
    

    <div class="container">
    <div class="item">我是一个div,我设置了上下外边距20px</div>
    <div class="item">我是一个div,我设置了上下外边距20px</div>
    <div class="item">我是一个div,我设置了上下外边距20px</div>
    </div>
    效果如下:

    可以看到下面的item的外边距发生了折叠

    如果将上面的div结构改成如下:
    
    可以发现在第二个item中嵌套了一个div外层,依旧会发生外边距折叠,这就是上面说的是渲染之后的元素相邻而不是dom结构上的相邻(嵌套了一个div之后第二个item与上下两个item在dom结构上不是相邻的了,不过渲染之后依旧上下相邻,因此还是会产生外边距折叠的。)        
    

    <div class="container">
    <div class="item">我是一个div,我设置了上下外边距20px</div>
    <div>
    <div class="item">我是一个div,我设置了上下外边距20px</div>
    </div>
    <div class="item">我是一个div,我设置了上下外边距20px</div>
    </div>
    效果如下:

    b:父元素和第一个/最后一个子元素之间 代码如下:
    

    <style>
    .parent {
    width: 600px;
    margin-top: 30px;
    margin-bottom: 30px;
    background: #a6d5ec;
    }

        .child {
            margin-top: 20px;
            margin-bottom: 20px;
            height: 50px;
            background-color: lightgray;
        }
    

    </style>
    <div class="parent">
    <div class="child">我是一个div子元素,我设置了上下外边距20px,我的父元素设置了上下外边距30px</div>
    <div class="child">我是一个div子元素,我设置了上下外边距20px,我的父元素设置了上下外边距30px</div>
    <div class="child">我是一个div子元素,我设置了上下外边距20px,我的父元素设置了上下外边距30px</div>
    <div class="child">我是一个div子元素,我设置了上下外边距20px,我的父元素设置了上下外边距30px</div>
    </div>
    此时就会发生外边距折叠:下图的第一个子元素和最后一个子元素都与父元素发生了外边距折叠,最后折叠结果表现为取大的那个值也就是父元素的30px;

    有时候我么并不希望发生外边距折叠,那触发bfc就可以为我们轻松解决这个问题:

    2:可以包含浮动的元素,防止“高度坍塌”。

    其实这也是使用overflow:auto,和overflow:hidden来清楚浮动的原理。其实就是触发了浮动元素的父元素bfc的布局, 从而可以包含浮动元素,闭合浮动。也就是bfc 可以根据子元素的情况来自适应高度,即便子元素是浮动的元素。
    

    这实际上是为我们解决浮动出现的高度“坍塌”实现了一种解决方案而且很优雅,当然也有其他方式来解决浮动出现的高度“坍塌”,后面我们在写一个专门解决浮动的文章。

    code:
    

    <style>
    .fl{
    float: left;
    }
    .cf{
    overflow: auto;
    }
    </style>

    <div class="container">
    <div class="item fl">我是一个div,我设置了float: left;我父元素div的高度是0</div>
    </div>
    <div class="container cf">
    <div class="item fl">我是一个div,我设置了float: left;但是我的父元素设置了overflow:aoto,触发了bfc,我父元素高度正常</div>
    </div>
    效果如下:

    前面两点都是bfc布局对于内部子元素的布局影响,第三点是和自己兄弟元素直接的影响了

    3:浮动元素的块级兄弟元素会无视这个浮动元素,并且总想沾满一行,这样就会被浮动元素所遮蔽一部分。这时候为这个块级兄弟元素触发bfc就可以避免被浮动元素遮蔽了。

    code:

    <style>
    .container{
    width: 1000px;
    background: #a6d5ec;
    height: 170px;
    margin-bottom: 20px;
    }
    .item{
    margin: 20px;
    width: 300px;
    /height: 50px;/
    border: 1px solid red;
    }

        .bfc{
            overflow: hidden;
        }
    
        .fl{
            float: left;
        }
        .fl-item{
            background: red;
        }
        
        .brother{
            background: #2aabd2;
        }
        .brother1{
            width: 400px;
        }
        .brother2{
            width: 500px;
        }
    </style>
    

    <div class="container">
    <div class="fl fl-item">我设置了float: left;挡在了部分(块级兄弟元素)的上面</div>
    <div class="brother">我是浮动元素的(块级兄弟元素),我没有触发bfc,我占满了一行可是我前部分被浮动元素挡在上面了</div>
    </div>
    <div class="container">
    <div class="fl fl-item">我设置了float: left;可还是挡不住触发了bfc的块级兄弟元素,但是宽度是多少我先占。</div>
    <div class="brother bfc">我是浮动元素的块级兄弟元素,我设置了overflow: hidden;触发bfc,我的宽度没有设置,先让浮动元素占据父元素的宽度,然后剩下的宽度都是我的了(我的宽度是自适应的)。左边的浮动元素再也挡不住我了,oh yeah~</div>
    </div>

    <div class="container">
    <div class="fl fl-item">我设置了float: left;挡不住触发了bfc的块级兄弟元素,但是宽度是多少我先占。</div>
    <div class="brother1 bfc brother">我是浮动元素的块级兄弟元素而且我有自己的固定宽度400px,我设置了overflow: hidden;触发bfc,先让浮动元素占据父元素的宽度,然后看剩下的宽度如果足够我用我就不换行,我只有400宽度足够我用了,我就不换行了,不然我就会自己换行。左边的浮动元素再也挡不住我了,oh yeah~</div>
    </div>

    <div class="container">
    <div class="fl fl-item">我设置了float: left;挡不住触发了bfc的块级兄弟元素,但是宽度是多少我先占。</div>
    <div class="brother2 bfc brother">我是浮动元素的块级兄弟元素而且我有自己的固定宽度500px,我设置了overflow: hidden;触发bfc,先让浮动元素占据父元素的宽度,然后看剩下的宽度如果足够我用我就不换行,不然我就会自己换行(剩下的跨大怒不够500px,所以我换行了)。左边的浮动元素再也挡不住我了,oh yeah~</div>
    </div>

    可以看出bfc的第三个特点对浮动元素的 块级别元素的影响。

    其中第二个块级别的兄弟元素不设置宽度,他的宽度是先让浮动元素占据父元素的宽度,然后自己自适应父元素的剩余宽度。这其实是一种经常用到的自适应布局技巧。父元素固定的情况下,浮动元素宽一点,那块兄弟元素就窄一点,浮动元素窄一点那么块兄弟元素就宽一点,两者的宽度相加始终等于父元素的宽度。

    第三个,块兄弟元素有自己的固定宽度而且剩余的宽度够用,那么还有多余那剩下的就给外边距了。

    第四个情况块兄弟元素哟自己的宽度而且剩余宽度不够自己用,那浏览器为了满足块兄弟元素所设置的宽度那就只能换行了。

    总结:

    BFC布局还是蛮有用的,触发bfc有若干方式,他能为我们解决一些问题,罗列出来的bfc的作用一共有三个,其中第一点第二点是合并外边距 和 解决浮动高度坍塌是对自己内部的渲染规则,而第三点阻止浮动元素遮蔽块兄弟元素则是bfc布局对外(对浮动的兄弟元素的渲染规则)。这三个特点特别是解决浮动元素的父元素高度“坍塌”和第三点自适应宽度布局是非常非常有用的。
    

    相关文章

      网友评论

          本文标题:bfc布局

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