浅谈对BFC的理解

浅谈对BFC的理解

对于前端开发人员来说肯定是知道盒模型(margin,border, padding, content)这个概念,对一个元素设置CSS,首先需要知道这个元素是block还是inline类型。而BFC就是用来格式化块级盒子,同样管理inline类型的盒子还有IFC,以及其他的FC。

1. FC的概念。

  Formatting Context:指页面中的一个渲染区域,并且拥有一套渲染规则,他决定了其子元素如何定位,以及与其他元素的相互关系和作用。

2. 什么是BFC

2.1 概念

块级格式化上下文,它是指一个独立的块级渲染区域,只有Block-level BOX参与,该区域拥有一套渲染规则来约束块级盒子的布局,且与区域外部无关。

注意: BFC 是W3C CSS 2.1 规范中的一个概念,在CSS3中被修改为float root。

2.2 BFC的生成

  1. 浮动元素(float: left | right)
  2. 绝对定位元素(position: absolute | fixed)
  3. overflow的值不为visible
  4. 行内块元素(display:inline-block)
  5. 表格单元格(display:table-cells,td, th)
  6. 表格的标题(display:table-captions)
  7. 注意:
    • disable:table之所以也可以是因为table默认会生成一个匿名的table-cell。正是因为匿名的table-cell生成了BFC
    • 是这些元素创建了BFC,他们本身不是BFC

2.3 BFC的约束规则

  1. 浏览器对于BFC这块区域的约束规则如下:

    • 生成BFC元素的子元素会一个接一个的放置。垂直方向上他们的起点是一个包含块的顶部,两个相邻子元素之间的垂直距离取决于元素的margin特性。在BFC中相邻的块级元素外边距会折叠(即margin重叠)
    • 生成BFC元素的子元素中,每一个子元素做外边距与包含块的左边界相接触,(对于从右到左的格式化,右外边距接触右边界),即使浮动元素也是如此(尽管子元素的内容区域会由于浮动而压缩),除非这个子元素也创建了一个新的BFC(如它自身也是一个浮动元素)
  2. 网友解析

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

    • 垂直方向上的距离由margin决定。(完整的说法是:属于同一个BFC的两个相邻Box的margin会发生重叠,与方向无关。)

    • 每个元素的左外边距与包含块的左边界相接触(从左向右),即使浮动元素也是如此。(这说明BFC中子元素不会超出他的包含块,而position为absolute的元素可以超出他的包含块边界)

    • BFC的区域不会与float的元素区域重叠

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

    • BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面元素,反之亦然

  3. css相关规则

    • Block元素会扩展到与父元素同宽,所以block元素会垂直排列
    • 垂直方向上的两个相邻DIV的margin会重叠,而水平方向不会(此规则并不完全正确)
    • 浮动元素会尽量接近往左上方(或右上方)
    • 为父元素设置overflow:hidden或浮动父元素,则会包含浮动元素

2.4 BFC的应用

  1. 防止margin重叠

    • 案例上下margin重叠

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      <!--
      * @Autor: Clairoll
      * @Date: 2020-12-14 11:18:24
      * @LastEditTime: 2020-12-14 11:39:56
      * @Email: [email protected]
      * @description:
      -->
      <!DOCTYPE html>
      <html lang="en">

      <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Document</title>
      </head>

      <style>
      html,
      body {
      height: 100%;
      width: 100%;
      margin: 0;
      padding: 0;
      }
      #map {
      padding: 0;
      }
      .first {
      margin: 20px;
      background: lightgreen;
      width: 100px;
      height: 100px;
      }
      ul {
      /* display:inline-block; */
      margin: 10px;
      background: lightblue;
      }

      li {
      margin: 25px;
      }
      </style>



      <body class="claro">
      <div class="first"></div>
      <ul>
      <li>1</li>
      <li>2</li>
      <li>3</li>
      </ul>
      </body>

      </html>

      undefined

    • 解决

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      <!--
      * @Autor: Clairoll
      * @Date: 2020-12-14 11:18:24
      * @LastEditTime: 2020-12-14 11:44:53
      * @Email: [email protected]
      * @description:
      -->
      <!DOCTYPE html>
      <html lang="en">

      <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Document</title>
      </head>

      <style>
      html,
      body {
      height: 100%;
      width: 100%;
      margin: 0;
      padding: 0;
      }
      #map {
      padding: 0;
      }
      .first {
      margin: 20px;
      background: lightgreen;
      width: 100px;
      height: 100px;
      }
      ul {
      display:inline-block; // 通过此处生成BFC
      /* overflow:hidden; */
      /*float: left;*/
      /*position: absolute;*/
      margin: 10px;
      background: lightblue;
      }

      li {
      margin: 25px;
      }
      </style>



      <body class="claro">
      <div class="first"></div>
      <ul>
      <li>1</li>
      <li>2</li>
      <li>3</li>
      </ul>
      </body>

      </html>

      undefined

  2. 浮动相关布局问题

  3. 多栏布局

上次更新 2021-01-28