概述

说到BFC,其实刚开始我也很迷,翻看了一些文档后打算来 总结一下,首先,BFC其实就是一种布局,说到CSS布局,大抵也就是普通流、浮动(元素会脱离普通流)、定位(元素会脱离普通流),BFC也属于普通流,加了BFC样式的元素像是给元素加了个结界,结界内部的元素不会影响外面的元素,被隔离开了。

BFC规则

• BFC就是一个块级元素,块级元素会在垂直方向一个接一个的排列;
• BFC样式的元素像是给元素加了个结界,结界内部的元素不会影响外面的元素,被隔离开了;
• 垂直方向的距离由margin决定, 属于同一个BFC的两个相邻的标签外边距会发生重叠;
• 计算BFC的高度时,浮动元素也参与计算;
• BFC布局是可以通过一些条件触发的,从而实现布局上的需求或解决一些问题;
• BFC就是一个工具,知道其是什么且怎么用就好;
• BFC可以看做是一个CSS元素属性

BFC触发条件

• 根元素(<html>)
• float值非none,即left,right)
• overflow值非visible即hidden,auto,scroll
• display值为inline-block、table-cell、table-caption、table、table-row、table-row-group、table-header-group、table-footer-group、inline-table、flow-root、flex、inline-grid、inline-flex。
• position值为absolute、fixed

注意 :
1、并不是所有元素都是BFC,只有满足了BFC的条件后,此元素才成为了1个BFC。
2、一个BFC区域,只包含其所有子元素,不包含子元素的子元素,举个例子,爷爷只养儿子不养孙子,孙子是儿子负责。

举个例子:

<body>
    <div class="test1"></div>
    <div class="test2"></div>
    <div class="test2">
      <h1>hello</h1>
      <h1>world!</h1>
    </div>
  </body>

上述代码,body元素算1个BFC,其子元素为test1,test2,但不包括test2里的两个h1标签,此时test2也不是BFC,因为不满足任何BFC条件。
要想test2成为一个BFC,给其设置为上述的任何一个条件即可

<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .test2 {
        overflow: hidden;
      }
    </style>
  </head>
  <body>
    <div class="test1"></div>
    <div class="test2"></div>
    <div class="test2">
      <h1>hello</h1>
      <h1>world!</h1>
    </div>
  </body>
</html>

BFC的应用场景

1、属于同一个BFC的两个相邻容器的上下margin会重叠

<html>
  <head>
    <style type="text/css">
      .top {
        width: 200px;
        height: 200px;
        background: red;
        margin-bottom: 40px;
      }
      .bottom {
        width: 200px;
        height: 200px;
        background: green;
        margin-top: 60px;
      }
    </style>
  </head>
  <body>
    <div class="top"></div>
    <div class="bottom"></div>
  </body>
</html>

效果图:

如图所示绿色盒子的上边距是60px,红色盒子的下边距是40px,会选取最大的60px。这种现象叫做margin塌陷。
原因:因为此时红盒子和绿盒子属于同一个BFC,也就是根元素(<html>),BFC的特性1规定“属于同一个BFC的两个相邻容器的上下margin会重叠,故两者上下边距发生重叠”

解决方案:
分离两个盒子,使它们处于不同的BFC就互不干涉了,给绿盒子加个div,其式样为overflow:hidden,分离BFC后就可以解决 margin重叠的问题了。

<html>
  <head>
    <style type="text/css">
      .top {
        width: 200px;
        height: 200px;
        background: red;
        margin-bottom: 40px;
      }
      .bottom {
        width: 200px;
        height: 200px;
        background: green;
        margin-top: 60px;
      }
      .box {
        overflow: hidden;
      }
    </style>
  </head>
  <body>
    <div class="top"></div>
    <div class="box">
      <div class="bottom"></div>
    </div>
  </body>
</html>



2、计算BFC高度时浮动元素也参与计算

<html>
  <head>
    <style type="text/css">
      .outside {
        border: 10px solid blue;
      }
      .inside {
        width: 200px;
        height: 200px;
        background: yellowgreen;
        /* float: left; */
      }
    </style>
  </head>
  <body>
    <div class="outside">
      <div class="inside"></div>
    </div>
  </body>
</html>

我们先看下正常情况,有两个盒子(div)=》outside为父元素,inside为子元素。父元素的样式设置了边框,目的想包裹住子元素。
效果图:

下面我们把子元素设置浮动,脱离文档流。float:left;

<html>
  <head>
    <style type="text/css">
      .outside {
        border: 10px solid blue;
      }
      .inside {
        width: 200px;
        height: 200px;
        background: yellowgreen;
        float: left;
      }
    </style>
  </head>
  <body>
    <div class="outside">
      <div class="inside"></div>
    </div>
  </body>
</html>

效果图:

子元素设置了浮动,脱离了文档流,所以造成上图现象。
原因:父元素没有设置高度且子元素设置浮动的时候,父元素就会出现高度塌陷。
来我们看下给父元素设置高度是什么效果。

<html>
  <head>
    <style type="text/css">
      .outside {
        height: 200px;
        border: 10px solid blue;
      }
      .inside {
        width: 200px;
        height: 200px;
        background: yellowgreen;
        float: left;
      }
    </style>
  </head>
  <body>
    <div class="outside">
      <div class="inside"></div>
    </div>
  </body>
</html>

解决方案:
要么给父元素添加高度,要么给父元素样式添加overflow:hidden

<html>
  <head>
    <style type="text/css">
      .outside {
        overflow: hidden;
        border: 10px solid blue;
      }
      .inside {
        width: 200px;
        height: 200px;
        background: yellowgreen;
        float: left;
      }
    </style>
  </head>
  <body>
    <div class="outside">
      <div class="inside"></div>
    </div>
  </body>
</html>


原因:给父元素添加样式overflow:hidden。父元素触发了BFC,BFC特性规定计算BFC高度时浮动元素也参与计算,这里子元素设置了浮动,因为BFC所以其高度仍计算到父元素内,从而解决了高度塌陷的问题。

3、BFC的区域不会与浮动容器发生重叠
两个相关的盒子,盒子1设置了左浮动,脱离了文档流,所以不会自适应两栏。两个盒子发生了重叠。

<html>
  <head>
    <style type="text/css">
      .left {
        width: 100px;
        height: 200px;
        background: yellowgreen;
        float: left;
      }
      .right {
       width: 300px;
       height: 300px;
        background: blue;
      }
    </style>
  </head>
  <body>
    <div class="left"></div>
    <div class="right"></div>
  </body>
</html>

效果图:

解决方案:
给右侧元素设置样式overflow:hidden,使得右侧元素触发BFC,BFC特性规定:BFC的区域不会与浮动容器发生重叠,触发BFC解决重叠问题,实现自适应两栏效果。

<html>
  <head>
    <style type="text/css">
      .left {
        width: 100px;
        height: 200px;
        background: yellowgreen;
        float: left;
      }
      .right {
        width: 300px;
        height: 300px;
        overflow: hidden;
        background: blue;
      }
    </style>
  </head>
  <body>
    <div class="left"></div>
    <div class="right"></div>
  </body>
</html>

效果图:

4、BFC内的容器在垂直方向依次排列
类似正常情况下块元素在垂直方向上依次排列,较易理解。
5、BFC是独立容器,容器内部元素不会影响容器外部元素
(解决包含塌陷)

<head>
    <style>
      .father {
        width: 300px;
        height: 300px;
        background-color: blueviolet;
      }
      .son {
        width: 100px;
        height: 100px;
        background: burlywood;
        margin-top: 50px;
      }
    </style>
  </head>
  <body>
    <div class="father">
      <div class="son"></div>
    </div>
  </body>

效果图:

原因:
父元素也跟着子元素的margin-top下移了50px;
解决方案:
设置父元素为一个BFC区域

 <head>
    <style>
      .father {
        width: 300px;
        height: 300px;
        background-color: blueviolet;
        overflow: hidden;
      }
      .son {
        width: 100px;
        height: 100px;
        background: burlywood;
        margin-top: 50px;
      }
    </style>
  </head>
  <body>
    <div class="father">
      <div class="son"></div>
    </div>
  </body>

效果图:

7、使用BFC实现左侧盒子定宽,右侧盒子自适应布局
左侧设置为浮动,右侧也设置为浮动,右侧的宽度计算为100%-左侧

<style>
     .left {
       width: 300px;
       height: 600px;
       background-color: aqua;
       float: left;
     }
     .right {
       /* width: calc(100% - 300px); */
       float: left;
       height: 600px;
       background-color: blueviolet;
     }
   </style>
 </head>
 <body>
   <div class="left"></div>
   <div class="right"></div>
 </body>

不加BFC的效果图:

加了BFC的效果图:

补充知识点:

使用display属性能够将三者任意转换:
   (1)display:inline;转换为行内元素
   (2)display:block;转换为块状元素
   (3)display:inline-block;转换为行内块状元素

① 行内元素:

(1)设置宽高无效
(2)对margin仅设置左右方向有效,上下无效;padding设置上下左右都有效,即会撑大空间
(3)不会自动进行换行

② 块状元素:

(1)能够识别宽高
(2)margin和padding的上下左右均对其有效
(3)可以自动换行
(4)多个块状元素标签写在一起,默认排列方式为从上至下

③行内块状元素特征:

(1)不自动换行
(2)能够识别宽高
(3)默认排列方式为从左到右

使用display属性能够将三者任意转换:

(1)display:inline;转换为行内元素
(2)display:block;转换为块状元素
(3)display:inline-block;转换为行内块状元素

参考文章:https://www.itcast.cn/news/20...
https://blog.csdn.net/leelxp/...

03-05 14:08