简单聊聊BFC

2,415 阅读3分钟

最近刷面试题,又遇到了 BFC 有关的问题,不出意外的又忘了,BFC 应该属于著名的“八股文”问题吧。

随着 Flex、Grid 布局的兴起,已经不会有人再用 float 去实现多栏布局了吧,使用 float 的机会几乎绝迹,感觉仅剩的用法就是在输入框、标题栏末尾的 × 号了。

在平时的项目中,基本接触不到 BFC ,每次看到这个概念,都要重新查阅一遍。在此写篇文章,巩固一下这方面的知识吧。

概念

BFC,全称 Block Formatting Context,意为块格式化上下文MDN 上的定义是:BFC 是 Web 页面的可视 CSS 渲染的一部分,是块级盒子的布局过程发生的区域,也是浮动元素与其他元素交互的区域。

通俗来讲:BFC 是一个独立的容器,在这个容器的元素布局不受外部影响,也不会影响到外部布局。

解决的问题

概念很绕,也没啥理解的价值,只要记住 BFC 一般用于处理这几种问题就好了

高度塌陷

看下面这个例子,给子 div 设置了浮动,导致其脱离了文档流,父元素高度塌陷了。

通过给容器设置 display: flow-root,使其变为 BFC,在计算高度时包含内部浮动元素,解决高度塌陷。

HTML

<section>
  <div class="box">
    <div class="float">我是一个浮动的盒子</div>
    <p>我是普通容器里的文字</p>
  </div>
</section>
<section>
  <div class="box" style="display: flow-root">
    <div class="float">我是一个浮动的盒子</div>
    <p>
      我是
      <code>display:flow-root</code>
      容器里的文字
    </p>
  </div>
</section>

CSS

section {
  height: 150px;
}
.box {
  background-color: rgb(224, 206, 247);
  border: 5px solid rebeccapurple;
}
.box[style] {
  background-color: aliceblue;
  border: 5px solid steelblue;
}
.float {
  float: left;
  width: 200px;
  height: 100px;
  background-color: rgba(255, 255, 255, 0.5);
  border: 1px solid black;
  padding: 10px;
}

image.png

外边距重叠

两个块级元素的上外边距和下外边距可能会合并为一个外边距,其值会取其中值大的那个,这种行为就是外边距折叠。重叠只会出现在垂直方向

通过给容器设置 display: flow-root,使其变为 BFC,与其他外部元素互不影响,解决外边距重叠。

HTML

<div class="container">
  <div>
    <div class="box">我是普通容器中的盒子</div>
  </div>
  <div class="box">我是普通盒子</div>
</div>
<div class="container">
  <div style="display: flow-root">
    <div class="box">我是 BFC 中的盒子</div>
  </div>
  <div class="box">我是普通盒子</div>
</div>

CSS

.container {
  border: 5px solid rebeccapurple;
}
.box {
  width: 200px;
  height: 50px;
  background-color: rgb(224, 206, 247);
  margin: 50px;
}

image.png

浮动元素覆盖

浮动元素会脱离文档流,导致覆盖另一个元素,可以使另一元素成为 BFC 与浮动元素互不影响。

HTML

<div class="container">
  <div class="float">我是浮动的盒子</div>
  <div class="box">我是普通盒子</div>
</div>
<div class="container">
  <div class="float">我是浮动的盒子</div>
  <div class="box" style="display: flow-root">我是普通盒子</div>
</div>

CSS

.container {
  border: 5px solid rebeccapurple;
}
.box {
  width: 200px;
  height: 200px;
  background-color: rgb(224, 206, 247);
}
.float {
  width: 100px;
  height: 100px;
  float: left;
  background-color: aliceblue;
}

image.png

以上就是一般使用 BFC 处理的三种问题。

设置 BFC

一般有以下方式设置 BFC

  • 根元素:<html>
  • 浮动元素:float 值不为 none
  • 绝对定位元素:positionabsolutefixed
  • 行内块元素:display 值为 inline-block
  • 表格元素:display 值为 tabletable-celltable-captioninline-table
  • overflow 值不为 visibleclip 的块元素
  • displayflow-root 的元素
  • contain 值为 layoutcontent 或 paint 的元素
  • 弹性元素:display 值为 flex 或 inline-flex 元素的直接子元素
  • 网格元素:display 值为 grid 或 inline-grid 元素的直接子元素
  • 多列容器:column-count 或 column-width 值不为 auto 的元素
  • column-span 值为 all 的元素始终会创建一个新的 BFC,即使该元素没有包裹在一个多列容器中

备注:  flex/grid 容器(display:flex/grid/inline-flex/inline-grid)建立新的 flex/grid 格式上下文,除布局之外,它与 BFC 类似。flex/grid 容器中没有可用的浮动子级,但排除外部浮动和阻止外边距重叠仍然有效。

结语

如果文中有错误或不严谨的地方,请务必给予指正,十分感谢。

如果喜欢或者有所启发,欢迎点赞关注,鼓励一下新人作者。