# BFC 的理解和最佳实践

关于答案解析

  • 有关 CSS 中 BFC 相关的面试题答案解析过程是根据自身项目实践以及查阅官方文档等最终的得出结论。
  • 仅供学习参考,评论区感谢补充和纠错 !

# 1、什么是 BFC ?

通俗来讲

BFC(Block Formatting Context)直译为 “块级格式化上下文”

  • 也就是说,它是页面上的一个隔离的独立容器,是一个独立的渲染区域。
  • 即是块盒子(Box)的布局过程发生的区域,也是浮动元素与其他元素交互的区域。
  • 容器里的子元素不会影响到外面的元素,反之亦然

不过,在我们 BFC 深入之前,我们先来看看常规流(Normal Flow),当然,我们也可以叫做文档流,因为也可用于文档排列布局。

# 2、常规流与非常规(浮动)

# ①、常规流

在常规流中,都有以下特点:


内联盒子:水平排列,直到当行被占满之后换行。只有水平外边距、边框和内边距会被保留。

块级盒子:占满一行,下一个自动往下补齐。

  • 同级盒子间的垂直距离会由margin属性决定,相邻两个块级盒子之间的垂直间距会遵循外边距折叠原则被折叠。
  • 各盒子元素按照其在 HTML 中先后位置,至左向右至上而下布局。

# ②、浮动

非常规流:


当然,有常规流,就会有不常规流,浮动(Float)就是一个例子。

  • 当一个元素浮动之后,它会被移出正常的文档流,然后向左或者向右平移,一直平移直到碰到了所处的容器的边框,或者碰到另外一个浮动的元素。
  • float: CSS 属性指定一个元素应沿其容器的左侧或右侧放置,允许文本和内联元素环绕它。

image-20211128215412868

# 3、BFC 可以解决什么问题及作用

我们知道,BFC 是属于常规流,是元素的一种属性

当某个元素拥有该属性时候,就可以看成是隔离出来的独立容器。无论里面的元素怎么变化,都不会影响到外面的元素。

有以下条件可以创建 BFC:

  • 方法一:float 的值不是 none

    • 该方法可以实现效果,但没有意义,不可能随便给盒子设置浮
  • 方法二:display 的值是 inline-block、flex 或 inline-flex

    • 该方法可以实现效果,但没有意义,不可能随便改变盒子为行内块
  • 方法三:position 的值不是 static 或者 relative

    • 该方法可以实现效果,但不靠谱
  • 方法四:overflow 的值不为 visible

    • overflow:hidden; 该方法可以实现效果,是非常好用的让盒子形成 BFC 的方法,但不能满足所有的场景

# ①、解决外部边距重叠

<style>
  .box {
    width: 200px;
    height: 50px;
    margin: 50px;
    border: 1px #fff solid;
  }
</style>
<body>
  <div class="container">
    <div class="box">box1</div>
  </div>
  <div class="container">
    <div class="box">box2</div>
  </div>
</body>

image-20220412102358940

从上图中可以看出

  • 垂直方向上下 margin 会重合距离依然是:50px,我们可以触发 BFC 来避免这个问题。
  • 通过设置 overflow 属性,从而触发 BFC,解决外部边距重叠问题。
.container {
  overflow: hidden; /* 触发BFC 解决以上边距重叠问题 */
}

image-20220412102857668

# ②、盒子 margin 塌陷问题

TIP

当我们需要在一个父元素中需要写一些列表项进行包裹时,然而,使用 float 就会导致以下结果

<style>
  .container {
    border: 1px solid red;
    width: 400px;
  }
  .box {
    border: 1px green solid;
    float: left; /* 浮动导致父元素内容塌陷 */
    width: 100px;
    height: 100px;
    background: skyblue;
  }
</style>
<body>
  <div class="container">
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
  </div>
</body>

image-20220412104030904

我们希望父元素包裹所有的子元素,然而因为 float 脱离了正常的文档流,无法包裹,所以,我们可以通过 overflow 清除浮动。

.container {
  border: 1px solid green;
  width: 400px;
  overflow: hidden;
  /* 添加overflow:hidden; 创建BFC,清除浮动所带来的塌陷 */
}

image-20220412104719405

# ③、阻止元素被浮动元素覆盖

没有实际意义,实际开发不会这么用,只具有理论意义

但要明白需要并排显示的盒子,要么都浮动,要么都不写,以下的写法是不合法规范的

<style>
  .float-div {
    float: left;
    width: 50px;
    height: 50px;
    border: 1px solid skyblue;
  }
  .normal-div {
    width: 200px;
    height: 200px;
    border: 1px solid skyblue;
  }
</style>
<body>
  <div class="float-div">box1</div>
  <div class="normal-div">box2</div>
</body>

image-20220412110256491

同样,我们可以利用 overflow 触发 box2 的 BFC,从而消除浮动,达到我们想要的效果。实际开发不会这样写,只需了解即可。

.normal-div {
  width: 200px;
  height: 200px;
  border: 1px solid skyblue;
  overflow: hidden; /* 触发了BFC */
}

image-20220412110748298

# 4、浏览器差异

了解即可


  • IE6、7 浏览器使用 haslayout 机制 和 BFC 规范略有差异

    • 比如:IE 浏览器可以使用 zoom:1 属性,让盒子拥有 layout
  • 如果要制作兼容到 IE6、7 的网页时,尽量让网页布局变得简单,内部有浮动的盒子要设置 height 属性,规范编程,就没有问题

# 5、清除浮动企业解决方案

清除浮动

浮动一定要封闭到一个盒子中,否则就会对页面后续元素产生影响

# ①、清除浮动方法一

方法 1

  • 让内部有浮动的父盒子形成 BFC,它就能关闭住内部的浮动。
  • 此时,最好的方法就是 overflow: hidden; 属性

此方法以上解析过程已给出案例,不再演示

# ②、清除浮动方法二

方法 2

  • 给后面的父盒子设置 clear: both; 属性
  • clear 表示清除浮动对自己的影响,both 表示左右浮动都清除

该方法不推荐,不推荐,不推荐

# ③、清除浮动方法三

方法 3

  • 使用 ::after 伪元素 给盒子添加最后一个子元素
  • 并且给 ::after 设置 clear:both;

强烈推荐使用 !!!

<style>
  div {
    border: 1px solid red;
    margin-bottom: 20px;
  }
  /* 添加伪元素 ::after 匹配选中的元素的最后一个子元素 */
  .clearfix::after {
    content: "";
    clear: both;
    /* 转为块级元素 */
    display: block;
  }
  p {
    width: 100px;
    height: 100px;
    background-color: skyblue;
    margin-right: 10px;
    float: left;
  }
</style>
<body>
  <div class="clearfix">
    <p></p>
    <p></p>
  </div>
  <div class="clearfix">
    <p></p>
    <p></p>
  </div>
</body>

image-20220412120824343

# ④、清除浮动方法四

方法 4

  • 在两个父盒子之间 "隔墙" 隔一个携带 clear: both; 的盒子

不推荐,不推荐,不推荐 !

上次更新时间: 6/8/2023, 9:23:17 PM

大厂最新技术学习分享群

大厂最新技术学习分享群

微信扫一扫进群,获取资料

X