一、BFC是什么

我们在页面布局的时候,经常出现以下情况:

  • 这个元素高度怎么没有了?
  • 这个两栏布局怎么没法自适应?
  • 这两个元素的间距怎么有点小奇怪?

原因是元素之间相互影响,导致意料之外的情况发生,这里牵涉到BFC概念
BFC,块级格式化上下文,它是页面的一块渲染区域,并有一套自己的渲染规则:

  • 内部的盒子会在垂直方向上一个接一个的放置
  • 对于同一个BFC的两个相邻的盒子的margin会发生重叠,与方向无关
  • 每个元素的左外边距与包含块的左边界相接触(从左到右),即使浮动元素也是如此
  • BFC的区域不会与float的元素区域重叠
  • 计算BFC的高度时,浮动子元素也参与计算
  • BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之亦然

BFC目的是形成一个相对于外界完全独立的空间,让内部的子元素不会影响到外部的元素

二、触发条件

  • 根元素,即HTML元素
  • 浮动元素:float值为 left, rgiht
  • overflow 值不为 visible, 为 auto/scroll/hidden
  • display 的值为 inline-block, inltable-cell, table-caption, table, inline-table, flex, inline-flex, gird, inline-grid
  • position的值为absolute或fixed

    三、应用场景

    1、防止外边距重叠(塌陷)

    1. <style>
    2. p {
    3. color: #f55;
    4. background: #fcc;
    5. width: 200px;
    6. line-height: 100px;
    7. text-align:center;
    8. margin: 100px;
    9. }
    10. </style>
    11. <body>
    12. <p>Haha</p >
    13. <p>Hehe</p >
    14. </body>

    页面显示如下:
    image.png
    两个p元素之间的距离为100px,发生了margin重叠(塌陷),以最大的为准,如果第一个P的margin为80的话,两个P之间的距离还是100,以最大的为准。
    前面讲到,同一个BFC的俩个相邻的盒子的margin会发生重叠。
    可以在p外面包裹一层容器,并触发这个容器生成一个BFC,那么两个p就不属于同一个BFC,则不会出现margin重叠。

    1. <style>
    2. .wrap {
    3. overflow: hidden;// 新的BFC
    4. }
    5. p {
    6. color: #f55;
    7. background: #fcc;
    8. width: 200px;
    9. line-height: 100px;
    10. text-align:center;
    11. margin: 100px;
    12. }
    13. </style>
    14. <body>
    15. <p>Haha</p >
    16. <div class="wrap">
    17. <p>Hehe</p >
    18. </div>
    19. </body>

    image.png

    2、清除内部浮动

    1. <style>
    2. .par {
    3. border: 5px solid #fcc;
    4. width: 300px;
    5. }
    6. .child {
    7. border: 5px solid #f66;
    8. width:100px;
    9. height: 100px;
    10. float: left;
    11. }
    12. </style>
    13. <body>
    14. <div class="par">
    15. <div class="child"></div>
    16. <div class="child"></div>
    17. </div>
    18. </body>

    页面显示如下:
    image.png
    BFC在计算高度的时候,浮动元素会参与计算,所以我们可以触发.par元素生成BFC,则内部浮动元素计算高度的时候会计算。

    1. .par {
    2. overflow: hidden;
    3. }

    页面如下图:
    image.png

    3、自适应多栏布局

    这里举个两栏的布局:

    1. <style>
    2. body {
    3. width: 300px;
    4. position: relative;
    5. }
    6. .aside {
    7. width: 100px;
    8. height: 150px;
    9. float: left;
    10. background: #f66;
    11. }
    12. .main {
    13. height: 200px;
    14. background: #fcc;
    15. }
    16. </style>
    17. <body>
    18. <div class="aside"></div>
    19. <div class="main"></div>
    20. </body>

    image.png
    前面讲到,每个元素的左外边距与包含块的左边界相接触。因此,虽然.aside为浮动元素,但是main的左边依然会包含块的左边相接触,而BFC的区域不会与浮动盒子重叠,所以我们可以通过触发main生成BFC,以此适应两栏布局

    1. .main {
    2. overflow: hidden;
    3. }

    这时候,新的BFC不会与浮动的.aside元素重叠。因此会根据包含块的宽度,和.aside的宽度,自动变窄
    效果如下:
    image.png

    小结

    可以看到以上几个案例,都体现了BFC实际上就是页面的一个独立容器,里面的子元素不会影响外面的元素。