什么是BFC

BFC(Block Fomatting Context)是一个经常能够见到的css概念,直译为"块级格式化上下文"。它是一个独立的渲染区域,只有Block-level box参与,它规定了内部的Block-level Box如何布局,并且与这个区域外部毫不相干。

Box Model 与 Fomatting Context

  • Box Model: 也就是我们常说的盒模型,其本质上为一个盒子,来封装周围的HTML元素。我们可以将一个盒子想象为CSS布局的基本单位,多个的盒子构成了整个界面的样式布局。元素的display属性决定了Box的类型,不同类型的Box意味着不同的渲染方式,比如耳熟能详的块级元素与行内元素。

    • block-level box : 如display为block、table、list-item的元素;

    • inline-level box : display为inline、inline-block、inline-table的元素

  • Formatting context : 格式化上下文,其实就是对上文提到的,Box渲染定位方式的一个官方的命名概念。最常见的就有Block Fomatting Context(BFC)、Inline Fomatting Conext(IFC),一般来说,这两种渲染定位方式中的Box就对应于上文中提到的两种Box类型。当然其他还有CSS3引入的Flex Fomatting Context(FFC),对应于弹性盒子,display为flex、inline-flex的元素。GFC(Grid Layout Context)对应于display为grid的元素。

Block Fomatting Conext

1. BFC的布局规则

在了解了Box与Formatting Context之后,我们就能知道,BFC就是一种为一块区域的总称,包括区域的布局机制、区域内的元素等,这块区域内的元素都由块级元素构成,且这块区域与外界的布局无关。BFC有如下的布局机制:

  • 内部的Box会在垂直方向,一个接一个地放置。

  • Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠。

  • 每个盒子(块盒与行盒)的margin box的左边,与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。

  • BFC的区域不会与float box重叠。

  • BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。

  • 计算BFC的高度时,浮动元素也参与计算。

2. 如何创建一个BFC

我们需要区别两个概念,“创建BFC”和“构成BFC”:

  • 首先BFC本身是一个区域,区域也是一个元素,这个元素属性满足一定的条件(也就是下文列举的条件)后,他就是创建一个BFC,是具有BFC机制的区域。

  • 区域中的子元素具有构成BFC的条件,如display属性为block的元素。对这个区域而言,如果它的display为block,那么它就是构成一个更大BFC的子元素。

以下列举的是摘自MDN官方文档的一部分创建BFC的规则:

  • 根元素()

  • 浮动元素(元素的 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 值不为 visible 的块元素

  • display 值为 flow-root 的元素

  • 弹性元素(display为 flex 或 inline-flex元素的直接子元素)

  • 网格元素(display为 grid 或 inline-grid 元素的直接子元素)

BFC的作用

1. 处理CSS外边距合并

  • CSS外边距合并 : 又可以称为margin塌陷或者margin越界。其实在BFC布局规则的第二点中也提到了。在BFC布局规则下,两个相邻的且垂直上下分布的元素之间,当他们的外边距相遇,如上元素的margin-bottm与下元素的margin-top相遇,那么这两者之间的外边距就会被合并。w3c上对CSS外边距合并问题做了一个很详细的介绍,CSS外边距合并

那么问题来了,为什么BFC的布局规则是引起外边距合并的原因,如何又用BFC来解决。BFC有一个非常重要的规则,那就是内外部相隔离,内外样式不会互相影响。如果两个会发生margin塌陷的子元素本身也是一个BFC,由于BFC内部的样式不会被外部影响,那么也就解决了这一问题。

2. 阻止元素被浮动元素覆盖

在一个正常的文档流下,两个兄弟元素之间,block元素可能会被一个float元素所覆盖,挤占正常的文档流。此时,通过改变这两个元素所在的区域为BFC,即可避免这一问题的发生。

3. 可以包含浮动元素

这个包含可以理解为物理意义的包括与涵盖,对于一个区域来说,它的高度可以自己设置,可以通过子元素撑开。如果它内部的子元素为浮动元素。由于浮动元素脱离了正常的文档流,所以哪怕浮动元素有高度,这块区域也无法被撑开。如果这块区域为一个BFC,那么这块区域依旧能够被正常撑开。

最后更新于