美文网首页
CSS-BFC初探

CSS-BFC初探

作者: YYPL | 来源:发表于2020-06-09 11:54 被阅读0次

    BFC

    块格式化上下文(Block Formatting Context,BFC)

    BFC产生的条件

    • 根元素

    • 元素的float属性不为none

    • 定位position: absolute;position: fixed;

    • display: inline-block;display: flex;display: inline-flex;display: table-cell;

    • overflow的值不为visible的块级元素,最常用的就是overflow: hidden;

    • display: flow-root;形成BFC最好的方式,没有副作用(存在浏览器兼容问题)


    BFC的特性

    • 内部的Box会在垂直方向,一个接一个地放置。

    • BFC区域不会与float box 重叠

    • 计算BFC高度的时候,浮动元素也会参与计算

    • BFC相当于页面上一个隔离的独立容器,容器中子元素不会影响到外面,外面的元素也不会影响到BFC里面的东西


    BFC的一般用途

    需要注意的是: 触发单个容器的BFC,并不会改变容器内部的文档流的性质,BFC可能会影响容器的高度值(会阻止父子元素外边距合并)

    一. BFC包含创建它的元素内部的所有内容

    上面是来自MDN的解释,简言之就是父容器可以完全包裹住,内部的子元素。而不会出现子元素溢出的情形

    首先看下父容器不触发BFC的效果

    BFC-父容器包住子元素,即使子元素为浮动元素-3-20200602.png
    父容器触发BFC的效果
    demo🌰 BFC-父容器包住子元素,即使子元素为浮动元素
    <style>
      .papa {
         border: 10px solid red;
         min-heiht: 10px;
        /* 下面的属性皆可以触发BFC     */
        display: flow-root;
        /*  position: absolute; */
        /*  display: inline-block; */
        /*  overflow: hidden; */
        /*  display: table-cell; */
      }
     .son {
        background-color: green;
        width: 300px;
        height: 110px;
        float: left;
        /*  margin-top: 100px; */
      }
    </style>
    <div class="papa">
      <div class="son"></div>
    </div>
    
    BFC-父容器包住子元素,即使子元素为浮动元素-1-20200602 上午11.36.09.png
    上面的情况就是父容器触发了BFC,所以父容器父包裹住子元素,而不让其溢出
    即是给子元素加外边距(margin),也只是会把父容器撑大而已
    /* div.son */
    margin-top: 110px;
    
    BFC-父容器包住子元素,即使子元素为浮动元素-2-20200602.png

    二. BFC分割相邻兄弟元素,达到左右布局的效果(结果类似浮动)

    demo 兄弟元素中另一个非浮动元素没有触发BFC的情形🌰
    BFC 分割兄弟元素,可形成左右布局(非浮动元素不触发BFC的情形)

    <style>
    .oldBrother {
        width: 110px;
        height: 200px;
        border: 2px solid blue;
        /* 浮动    */
        float: left;
    }
    .youngBrother {
        border: 4px solid red;
        width: 300px;
        height: 200px;
    }       
    </style>
    <div class="oldBrother"></div>
    <div class="youngBrother"></div>
    
    BFC划分兄弟元素界线(在不触发BFC的情况下)-20200602.png
    根据上面的代码及图片,原因可以很清楚的得知: div.oldBrother元素,设定了浮动(并没有清除浮动)从而脱离文档流,所以对于div.youngBrother元素而言div.oldBrother元素相当于不存在

    div.youngBrother这个非浮动元素触发BFC
    demo 🌰

    <style>
    .oldBrother {
        width: 110px;
        height: 380px;
        border: 2px solid blue;
        /* 浮动    */
        float: left;
    }
    .youngBrother {
        border: 4px solid red;
        width: 300px;
        height: 380px;
        /*  触发浮动 */
        overflow: hidden;
    }
    </style>
    <div class="oldBrother"></div>
    <div class="youngBrother"></div>
    

    分割兄弟元素,可形成左右布局(其中一个为浮动元素,另一个触发BFC)

    BFC划分兄弟元素界线(注意触发BFC的元素的margin-left的值必须大于另一个浮动元素的宽度)-20200602.png

    已经触发BFC的容器,不会影响到容器外面的元素,当然外面的元素也不会影响到BFC内部的元素。所以如上图所示: BFC的区域 div.youngBrother 不会与float boxdiv.oldBrother区域重叠

    ⚠️:需要注意的是上面的这种情形,要达到下图这种正常的左右布局的效果

    BFC划分兄弟元素界线-20200602.png
    需要给div.youngBrother 添加 margin-left,且其值应该大于浮动元素的宽度的值
    /* margin-left的值必须大于左边浮动元素的宽度 */
    margin-left: 125px;
    

    给父容器添加,清除浮动的属性,同样可以达到和触发BFC同样的效果
    demo 例子 给父容器常规的方法去除浮动,同样可以达到与触发父容器的BFC同样的效果

    <style>
      /* 清除浮动 */
      .clearfix::after {
          content: '';
          display: block;
          clear: both;
       }
     .papa {
         border: 10px solid red;
         min-heiht: 10px;
      }
      .son {
          background-color: green;
          width: 300px;
          height: 110px;
          float: left;
       }
    </style>
    <div class="papa clearfix">
      <div class="son"></div>
    </div>
    

    需要注意的是,我们使用常规方法清除浮动,并不会带来什么副作用。而触发父容器的BFC虽然可以达到清除浮动的效果,但同时也是带去一些副作用。所以始终不建议使用触发父容器BFC的方式,来清除浮动

    虽然dispaly: flow-root可以无副作用的,触发BFC,但是仍要考虑兼容性问题

    flow-root 触发BFC无副作用的方式-20200602-1.png

    三. BFC阻止父子元素外边距合并(不能阻止相邻兄弟元素的外边距合并)

    实例demo BFC阻止父子边距的合并;计算BFC高度的同时,浮动元素也会被计算进来

    <style>
      body {
        margin: 0;
        padding: 0;
      }
      header {
        margin-top: 50px;
        /* 触发了 BFC,阻止了header元素与h1元素的外边距合并  */
        background: red;
        /* 下面的两个条件都可以触发BFC */
        display: flow-root;
        /* overflow: hidden; */
      }
      h1 {
        margin: 50px 0 0 0;
        background-color: yellow;
      }
      ul li {
        list-style-type: none;
      }
      nav {
        background: pink;
        /* 下面的两个条件都可以触发BFC */
        display: flow-root;
        /* overflow: hidden; */
       }
      nav li {
        /*  计算BFC的高度时,内部的浮动元素也会被计算进去  */
        background-color: #fff;
        float:left;
        padding: 30px 10px;
        margin-bottom: 100px;
      }
    </style>
    <header id="header">
      <h1>Margin合并</h1>
      <nav>
        <ul>
          <li><a href="#">one</a></li>
          <li><a href="#">two</a></li>
          <li><a href="#">three</a></li>
        </ul>
      </nav>
    </header>
    

    效果如下:


    触发父容器 header标签 BFC的情况-2-20200602.png

    demo-🌰没触发父容器 header 元素 BFC的情况

    没触发父容器 header元素 BFC的情况-20200602.png

    对比上下两个demo,可以得出当在父容器header标签上触发了BFC的时候,是会阻止父容器外边距与子元素的外边距合并的。如果如没有在父容器header标签触发了BFC,则上🌰 图二中的headerh1(父元素与子元素)存在上边距合并的情况。

    至于在图二当没给nav元素触发浮动时,但是nav就像消失了似的。这是因为li设置了浮动,脱离文档流,导致li元素对于nav并不是可见的,就像nav元素自己内部什么都不存在一样。再者个如果出触发了nav元素的BFC,可以看出计算BFC高度的时候浮动元素也会参与进来

    使用BFC需注意

    上面我们举了一些🌰demo,BFC可以让父容器包住子元素,防止子元素溢出以及阻止父子元素外边距合并。但是在实际编写页面样式的时候,最好不使用BFC,因为产生BFC的同时也会带来一些不必要的副作用。当然如果display: flow-root被越来越多的浏览器接受,也可使用display: flow-root触发BFC,达到你的目的


    参考

    Lucy | CSS: What is Block Formatting Context (BFC)?

    CSS 101: Block Formatting Contexts

    前端精选文摘:BFC 神奇背后的原理 - 梦想天空(山边小溪) - 博客园

    块格式化上下文 - Web 开发者指南 | MDN


    版权声明:本文为博主原创文章,未经博主许可不得转载

    相关文章

      网友评论

          本文标题:CSS-BFC初探

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