其实在我们的实际开发过程中,很多时候都用到了 BFC 解决问题,但我们或许并不知道自己利用的就是 BFC 特性,这里专门介绍一下我们神通广大的 BFC

一、什么是BFC

BFC(Block Formatting Context)就是块级格式化上下文,是页面上一块独立的渲染区域,内部元素盒子都按照其特定的规则进行排列渲染,且区域内的布局与区域外的布局不相互影响。

二、BFC的渲染规则

  • 内部的盒子在垂直方向,一个一个地放置
  • 同一个 BFC 内两个相邻盒子的 margin 会重叠(取上下margin的最大值)
  • BFC 内部,每一个盒子的左 margin 都会与包含块的左 border 相接触,即使存在浮动也如此
  • 在计算 BFC 的高度时,其内部的浮动元素的高度也会参与计算
  • BFC 区域不会与区域外部的浮动元素重叠

三、如何生成BFC

  • 根元素 html 直接生成 BFC
  • overflow 值不为 visible 和 clip 的块元素
  • position 值为 absolute 或 fixed
  • float 值不为 none
  • display 值为 inline-block、flow-root、table、table-row、table-row-group、table-header-group、table-footer-group、table-cell、table-caption 等

四、BFC有何作用

1、避免margin重叠以及margin塌陷

margin重叠(合并):在垂直方向上,两个兄弟元素都设置了 margin,那么它们垂直方向的距离按理来说是两个 margin的和,但实际上会取两者的较大值,如下所示

  <style>
    div {
      width: 200px;
      height: 200px;
      line-height: 200px;
      text-align: center;
      border: 5px solid rgb(250, 134, 67);
    }  
    .margin1 {
      margin: 20px auto;
    }
    .margin2 {
      margin: 10px auto;
    }
  </style>

  <div class="margin1">我是margin1</div>
  <div class="margin2">我是margin2</div>

Alt
我们可以利用 BFC 来避免这一现象,可以将一个元素放到 BFC 内,这样两个盒子不在同一个 BFC 内就不会发生 margin 重叠,如下所示

  <style>
    .bfc {
      overflow: auto;
    }
  </style>

  <div class="margin2">我是margin2</div>
  <div class="bfc">
    <div class="margin1">我是BFC内的margin1</div>
  </div>

在这里插入图片描述
margin塌陷:父子元素之间没有其它内容(如 border/padding )时,会有margin塌陷的情况

父元素未设置 margin-top,子元素设置了 margin-top,会发生 margin 塌陷。预想的情况应该是子元素顶部距离父元素顶部为 margin-top,而实际上子元素顶部紧贴父元素顶部,而父元素顶部距离其它元素为 margin-top,看上去就像子元素带着父元素一起掉了下来

  <style>
    .bfc {
      width: 300px;
      height: 300px;
      background-color: rgb(42, 170, 164);
    }
    .margin1 {
      width: 200px;
      height: 200px;
      line-height: 200px;
      text-align: center;
      background-color: rgb(250, 134, 67);
      margin-top: 20px;
    }
  </style>

  <div class="bfc">
    <div class="margin1">我是margin1</div>
  </div>

在这里插入图片描述

父子元素都设置 margin-top,可能发生 margin 塌陷。当子元素margin > 父元素margin时显示正常,否则子元素的 margin-top 塌陷到父元素的 margin-top 中,子元素顶部与父元素顶部重合

  <style>
    .bfc {
      width: 300px;
      height: 300px;
      background-color: rgb(42, 170, 164);
      margin-top: 30px;
    }
    .margin1 {
      width: 200px;
      height: 200px;
      line-height: 200px;
      text-align: center;
      background-color: rgb(250, 134, 67);
      margin-top: 20px;
    }
  </style>

  <div class="bfc">
    <div class="margin1">我是margin1</div>
  </div>

在这里插入图片描述
我们可以触发父元素的 BFC 来避免这一现象,如下所示

  <style>
    .bfc {
      width: 300px;
      height: 300px;
      background-color: rgb(42, 170, 164);
      margin-top: 30px;
      overflow: auto;
    }
    .margin1 {
      width: 200px;
      height: 200px;
      line-height: 200px;
      text-align: center;
      background-color: rgb(250, 134, 67);
      margin-top: 20px;
    }
  </style>

  <div class="bfc">
    <div class="margin1">我是margin1</div>
  </div>

在这里插入图片描述

2、清除浮动,避免高度塌陷

子元素不设置浮动的情况下,当父元素不设置高度时,其高度会被子元素撑开。但是当子元素设为浮动元素时,由于子元素脱离了文档流,子元素原本的位置空间不被保留导致父元素高度为0,这就是高度塌陷现象,如下所示

  <style>
    .father {
      border: 5px solid rgb(250, 238, 67);
    }
    .bfc {
      overflow: auto;
    }
    .left {
      float: left;
      border: 5px solid rgb(250, 104, 67);
    }
  </style>

  <div class="father">
    <div class="left">我是float:left,父元素未设置高度,为0</div>
  </div>
  <div class="bfc">
    <div class="left">我是BFC内的float:left,父元素高度包含我的高度</div>
  </div>


此时我们需要清除浮动来避免这种现象。因为在计算 BFC 的高度时,其内部的浮动元素也会参与计算,因此我们可以激活父元素的 BFC 清除浮动,如下所示

  <style>
    .bfc {
      overflow: auto;
    }
  </style>

  <div class="father bfc">
    <div class="left">我是BFC内的float:left,父元素高度包含我的高度</div>
  </div>

3、避免浮动元素遮挡

BFC 内的盒子元素都遵循:盒子元素 margin 左侧与包含块的 border 左侧相接触。而文档流中不保留浮动元素原本的位置,导致紧跟其后的非浮动元素仿佛浮动元素不存在一样,补上浮动元素原本的位置,因此当非浮动元素与浮动元素处在同一BFC内时,会出现浮动元素遮挡非浮动元素的情况,如下所示。

  <style>
  	div {
      text-align: center;
      margin: 0 10px;
    }
    .div1 {
      width: 100px;
      height: 50px;
      line-height: 50px;
      float: left;
      border: 5px solid rgb(250, 134, 67);
    }
    .div2 {
      width: 200px;
      height: 100px;
      line-height: 100px;
      border: 5px solid rgb(250, 73, 67);
    }
  </style>

  <div class="div1">我是div1</div>
  <div class="div2">我是div2</div>

在这里插入图片描述
为避免这种情况,根据 BFC 渲染规则:BFC 区域不与外部的浮动元素重叠,我们可以将触发非浮动元素的 BFC,使其不与外部浮动元素重叠,如下所示

  <style>
    .div2 {
      width: 200px;
      height: 100px;
      line-height: 100px;
      /* 触发div2的BFC */
      overflow: auto;
      border: 5px solid rgb(250, 73, 67);
    }
  </style>

  <div class="div1">我是div1</div>
  <div class="div2">我是div2</div>

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐