时间: 2020-08-30|tag:49次围观|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的效果

CSS-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>

CSS-BFC初探插图1
BFC-父容器包住子元素,即使子元素为浮动元素-1-20200602 上午11.36.09.png

上面的情况就是父容器触发了BFC,所以父容器父包裹住子元素,而不让其溢出
即是给子元素加外边距(margin),也只是会把父容器撑大而已

/* div.son */margin-top: 110px;
CSS-BFC初探插图2
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>

CSS-BFC初探插图3
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)

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

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

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

CSS-BFC初探插图5
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,但是仍要考虑兼容性问题

CSS-BFC初探插图6
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>

效果如下:

CSS-BFC初探插图7
触发父容器 header标签 BFC的情况-2-20200602.png

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

CSS-BFC初探插图8
没触发父容器 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


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

文章转载于:https://www.jianshu.com/p/ee5cda12b9fa

原著是一个有趣的人,若有侵权,请通知删除

本博客所有文章如无特别注明均为原创。
复制或转载请以超链接形式注明转自起风了,原文地址《CSS-BFC初探
   

还没有人抢沙发呢~