BFC

60 阅读4分钟

BFC 是指块级格式化上下文,是一个 CSS 渲染的区域,并且这个区域内的元素会单独进行布局。

在 CSS 中,块级格式化上下文被创建时,会生成一个新的渲染区域,并且这个新的渲染区域与外部是隔离的。也就是说,在 BFC 中的元素布局不受外界元素的影响。

下列方式会创建块格式化上下文:

  • 文档的根元素(<html>)。
  • 浮动元素(即 float 值不为 none 的元素)。
  • 绝对定位元素(position 值为 absolute 或 fixed 的元素)。
  • 行内块元素(display 值为 inline-block 的元素)。
  • 表格单元格(display 值为 table-cell,HTML 表格单元格默认值)。
  • 表格标题(display 值为 table-caption,HTML 表格标题默认值)。
  • 匿名表格单元格元素(display 值为 table(HTML 表格默认值)、table-row(表格行默认值)、table-row-group(表格体默认值)、table-header-group(表格头部默认值)、table-footer-group(表格尾部默认值)或 inline-table)。
  • overflow 值不为 visible 或 clip 的块级元素。
  • display 值为 flow-root 的元素。
  • contain 值为 layoutcontent 或 paint 的元素。
  • 弹性元素(display 值为 flex 或 inline-flex 元素的直接子元素),如果它们本身既不是弹性网格也不是表格容器。
  • 网格元素(display 值为 grid 或 inline-grid 元素的直接子元素),如果它们本身既不是弹性网格也不是表格容器。
  • 多列容器(column-count 或 column-width (en-US) 值不为 auto,且含有 column-count: 1 的元素)。
  • column-span 值为 all 的元素始终会创建一个新的格式化上下文,即使该元素没有包裹在一个多列容器中(规范变更Chrome bug

一个元素如果设置了BFC,这个元素的子元素会在自己的 BFC 中进行布局,与外界元素隔离。

BFC 可以帮助我们解决一些布局问题,例如阻止元素垂直外边距的折叠。同时,使用 BFC 也需要注意性能问题,因为创建 BFC 会增加布局的计算量。

BFC的应用场景包括但不限于以下几种情况:

  1. 阻止外边距折叠问题:在标准文档流中,块级标签之间竖直方向的margin会以大的为准,这就是margin的塌陷现象。可以用overflow:hidden产生bfc来解决。
  2. 清除浮动:当一个元素设置了浮动(float)属性后,它会影响其后的元素布局。通过给其父元素添加overflow:hidden属性,可以创建一个BFC,从而清除浮动对其后元素的影响。
  3. 防止布局溢流:当一个元素的宽度设置为100%时,如果其父元素没有设置overflow属性,那么这个元素会溢流到其父元素的宽度。通过给父元素添加overflow:hidden属性,可以创建一个BFC,从而防止布局溢流。
  4. 布局隔离:有时候我们希望某个区域的布局独立于其他部分,例如一个登录表单希望无论其他页面如何变化,它的布局始终保持不变。通过给这个登录表单的父元素设置display:flow-root属性,可以创建一个BFC,从而隔离其布局。

以下是一个简单的示例,使用BFC实现阻止外边距折叠:

<!DOCTYPE html>
<html>
<head>
 <title>BFC Example</title>
 <style>
 .container {
 overflow: hidden; /* 创建BFC */
 }
 .box {
 width: 100px;
 height: 100px;
 margin: 10px;
 background-color: red;
 float: left;
 }
 </style>
</head>
<body>
 <div class="container">
 <div class="box"></div>
 <div class="box"></div>
 <div class="box"></div>
 </div>
</body>
</html>

在上面的示例中,我们创建了一个包含三个盒子的容器。容器使用了overflow: hidden属性,这会创建一个BFC。由于盒子都设置了浮动属性,如果没有BFC,它们之间的外边距会折叠。但是由于容器创建了BFC,外边距折叠被阻止了。

清除浮动:

<!DOCTYPE html>
<html>
<head>
 <title>Clear Float Example</title>
 <style>
 .container {
 overflow: hidden; /* 创建BFC,用于清除浮动 */
 }
 .box {
 width: 100px;
 height: 100px;
 float: left;
 background-color: red;
 }
 </style>
</head>
<body>
 <div class="container">
 <div class="box"></div>
 <div class="box"></div>
 <div class="box"></div>
 </div>
</body>
</html>

防止布局溢流:

<!DOCTYPE html>
<html>
<head>
 <title>Overflow Example</title>
 <style>
 .container {
 overflow: hidden; /* 创建BFC,防止布局溢流 */
 width: 300px;
 }
 .box {
 width: 100%;
 height: 100px;
 background-color: red;
 }
 </style>
</head>
<body>
 <div class="container">
 <div class="box"></div>
 <div class="box"></div>
 <div class="box"></div>
 </div>
</body>
</html>