block formatting contextsformatting contexts 格式化上下文的概念之一,formatting contexts 其中有几种类型,包括块格式化上下文 block formatting contexts、内联格式化上下文 inline formatting contexts 和灵活格式化上下文 flex formatting contexts。

块格式化上下文(Block formatting context,BFC) 是 Web 页面的可视 CSS 渲染的一部分,是块盒子的布局过程发生的区域,也是浮动元素与其他元素交互的区域。

文档最外层元素使用块布局规则或称为初始块格式上下文。这意味着 <html> 元素块中的每个元素都是按照正常流程遵循块和内联布局规则进行布局的。参与 BFC 的元素使用 CSS 框模型概述的规则,该模型定义了元素的边距、边框和填充如何与同一上下文中的其他块交互。

# 创建新的块格式上下文

<html> 元素不是唯一能够创建块格式上下文的元素。默认为块布局的任何元素也会为其后代元素创建块格式上下文。此外,还有一些 CSS 属性可以使元素创建一个 BFC,即使默认情况下它不这样做。
以下方式会创建块格式化上下文

  • 根元素(<html>)
  • 浮动元素(元素的 float 不是 none)
  • 绝对定位元素(元素的 position 为 absolute 或 fixed)
  • 行内块元素(元素的 display 为 inline-block)
  • 表格单元格(元素的 display 为 table-cell,HTML 表格单元格默认为该值)
  • 表格标题(元素的 display 为 table-caption,HTML 表格标题默认为该值)
  • 匿名表格单元格元素(元素的 display 为 table、table-row、 table-row-group、table-header-group、table-footer-group(分别是 HTML table、row、tbody、thead、tfoot 的默认属性)或 inline-table)
  • overflow 计算值 (Computed) 不为 visible 的块元素
  • display 值为 flow-root 的元素
  • contain 值为 layout、content 或 paint 的元素
  • 弹性元素(display 为 flex 或 inline-flex 元素的直接子元素)
  • 网格元素(display 为 grid 或 inline-grid 元素的直接子元素)
  • 多列容器(元素的 column-countcolumn-width(en-US) 不为 auto,包括 column-count 为 1)
  • column-span 为 all 的元素始终会创建一个新的 BFC,即使该元素没有包裹在一个多列容器中(标准变更Chrome bug)。

# BFC 创建例子

让我们看看几个例子,来理解创建 BFC 的效果。
在下面的示例中,我们在应用了边框的 <div> 中有一个浮动元素。该 div 的内容与浮动元素一起浮动。由于 float 的内容比它旁边的内容高,所以现在 DIV 的边框贯穿了 float。如流入和流出元素指南 guide to in-flow and out of flow elements 中所述,浮动已脱离文档流,因此 DIV 的背景和边框仅包含内容,而不包含浮动。
image.png
创建一个新的 BFC 将包含该浮动。在过去,一种典型的方法是设置 overflow: auto 或设置其他不是 overflow: visible 的值。
image.png
设置 overflow: auto 会自动创建包含浮动的新 BFC。现在,我们的 DIV 在布局中变成了一个迷你布局。任何子元素都将包含在其中。
使用 overflow 创建新的 BFC 的问题在于, overflow 属性用于告诉浏览器您希望如何处理溢出的内容。在某些情况下,当您纯粹使用此属性创建 BFC 时,您会发现不需要的滚动条或剪切阴影。另外,对于未来的开发人员来说,它可能不太可读,因为不能显式地表明为什么要使用溢出来实现这一目的。如果您使用了这个方法,最好对代码进行注释以便他人理解。

# 使用 display:flow-root 显式创建 BFC

使用 display: flow-root (或 display: flow-root list-item)将创建一个新的 BFC,而不会产生任何其他潜在的问题副作用。
image.png
使用 <div> 上的 display: flow-root ,该容器内的所有内容都参与该容器的块格式上下文,并且浮动不会从元素底部弹出。
flow-root 关键字的意义是,创建的内容本质上类似于一个新的根元素(如 <html> 所做),并确定这个新的上下文如何创建及其流布局如何实现。