CSS中的 BFC

444 阅读4分钟

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

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

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

理解上面内容需要先理解 BoxFormatting Context的概念。

Box: CSS布局的基本单位

  Box 是 CSS 布局的对象和基本单位, 直观点来说,就是一个页面是由很多个 Box 组成的。元素的类型和 display 属性,决定了这个 Box 的类型。 不同类型的 Box, 会参与不同的 Formatting Context(一个决定如何渲染文档的容器),因此Box内的元素会以不同的方式渲染。让我们看看有哪些盒子: block-level box:display 属性为 block, list-item, table 的元素,会生成 block-level box。并且参与 block fomatting context; inline-level box:display 属性为 inline, inline-block, inline-table 的元素,会生成 inline-level box。并且参与 inline formatting context; run-in box: css3 中才有, 这儿先不讲了。

Formatting context

  Formatting context 是 W3C CSS2.1 规范中的一个概念。它是页面中的一块渲染区域,并且有一套渲染规则,它决定了其子元素将如何定位,以及和其他元素的关系和相互作用。最常见的 Formatting context 有 Block fomatting context (简称BFC)和 Inline formatting context (简称IFC)。 CSS2.1 中只有 BFC 和 IFC, CSS3 中还增加了 GFC 和 FFC。

BFC

  BFC(Block Formatting Context)直译为“块级格式化范围”。是 W3C CSS 2.1 规范中的一个概念,它决定了元素如何对其内容进行定位,以及与其他元素的关系和相互作用。当涉及到可视化布局的时候,Block Formatting Context提供了一个环境,HTML元素在这个环境中按照一定规则进行布局。一个环境中的元素不会影响到其它环境中的布局。比如浮动元素会形成BFC,浮动元素内部子元素的主要受该浮动元素影响,两个浮动元素之间是互不影响的。这里有点类似一个BFC就是一个独立的行政单位的意思,也可以说BFC就是一个作用范围。可以把它理解成是一个独立的容器,并且这个容器的里box的布局,与这个容器外的毫不相干。

怎样才能形成BFC

float的值不能为none overflow的值不能为visible display的值为table-cell, table-caption, inline-block中的任何一个 position的值不为relative和static 

BFC的约束规则

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

看到以上的几条约束,可以联想起css的几条规则,Block元素会扩展到与父元素同宽,所以block元素会垂直排列,垂直方向上的两个相邻DIV的margin会重叠,而水平方向不会(此规则并不完全正确)。浮动元素会尽量接近往左上方(或右上方),为父元素设置overflow:hidden或浮动父元素,则会包含浮动元素