CSS中的BFC

1. 了解BFC之前

在了解什么是BFC之前,需要我们首先了解什么是Box、Formatting Context的概念。

1.1 Box: CSS布局的基本单位

在css布局中,我们最常见的布局方式就是盒子模型了。Box是CSS布局中的对象和基本单位,直观来说,就是一个页面是由很多的Box组成的。元素的类型和display属性决定了这个Box的类型。不同类型的Box会参与不同的Formatting Context,相应的Box内的元素也会以不同的方式渲染。

盒子模型(Box Model)如果按照浏览器的实现方式进行划分的话,分为IE盒子模型和标准盒子模型两大类。

其中IE盒子模型中的width和height包括border、padding和content部分,而标准盒子模型中的width和height则只是指content部分。

Box的种类:

  1. block-level box:display属性为block、list-item和table的元素
  2. inline-level box:display属性为inline、inline-block、inline-table的元素
  3. run-in box:CSS3中定义的
  4. flexibel-box:弹性盒子模型

1.2 Formatting Context: 格式化上下文

Formatting Context 是 W3C CSS2.1 规范中的一个概念。它指代的是页面中的一个渲染区域,并且拥有自己的一套渲染规范,它决定了其子元素如何定位以及与其他元素之间的相互作用关系。

最常见的Formatting Context有Block Formatting Context (BFC)和Inline Formatting Context (IFC)。CSS 2.1 中只有 BFCIFC,CSS 3 中增加了 GFCFFC

2. 什么是BFC

2.1 BFC定义

BFC直译为块级格式化上下文。它是一个独立的渲染区域,只有Block-level box参与,它规定了内部Block-level box如何布局,并且这个区域与外部毫不相干。

W3C规范中对BFC的定义是这样的:

Floats, absolutely positioned elements, block containers (such as inline-blocks, table-cells, and table-captions) that are not block boxes, and block boxes with ‘overflow’ other than ‘visible’ (except when that value has been propagated to the viewport) establish new block formatting contexts for their contents.
 
In a block formatting context, boxes are laid out one after the other, vertically, beginning at the top of a containing block. The vertical distance between two sibling boxes is determined by the ‘margin’ properties. Vertical margins between adjacent block-level boxes in a block formatting context collapse.
 
In a block formatting context, each box’s left outer edge touches the left edge of the containing block (for right-to-left formatting, right edges touch). This is true even in the presence of floats (although a box’s line boxes may shrink due to the floats), unless the box establishes a new block formatting context (in which case the box itself may become narrower due to the floats).

2.2 BFC的布局规则

浏览器对于 BFC 这块区域的布局规则规定如下:

  1. 生成 BFC 元素的子元素会一个接一个的放置。垂直方向上它们的起点是一个包含块的顶部,两个相邻子元素之间的垂直距离取决于元素的 margin 特性。在 BFC 中相邻的块级元素外边距会折叠。

  2. 生成 BFC 元素的子元素中,每一个子元素的左外边距与包含块的左边界相接触,(对于从右到左的格式化,右外边距接触右边界),即使是浮动元素也是如此(尽管子元素的内容区域会由于浮动而压缩),除非这个子元素也创建了一个 BFC (如它自身也是一个浮动元素)。

更详细的布局规则如下:

  1. 内部的 Box 会在垂直方向上一个接一个的放置。

  2. 垂直方向上的距离由 margin 决定,(完整的说法是:属于同一个 BFC 的两个相邻 Box 的 margin 会发生重叠,与方向无关。)

  3. 每个元素的左外边距与包含块的左边界相接触(从左向右),即使浮动元素也是如此。(这说明BFC中子元素不会超出它的包含块,而position为absolute的元素可以超出它的包含块)

  4. BFC的区域不会与float的元素区域重叠。

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

  6. BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面元素,反之亦然。

2.3 BFC的三大特性

  1. 阻止垂直外边距折叠(Margin Collapse)【创建了BFC的元素不会与它们的子元素发生外边距折叠。】

  2. 不会重叠浮动元素【与浮动元素相邻的、创建了BFC的元素,都不能与浮动元素相互覆盖。利用该特性,可以实现两栏布局。】

  3. 可以包含浮动【创建了BFC的元素,其子元素也会参与高度的计算,即不会发生高度塌陷。】

2.4 BFC的生成

  1. 根元素

  2. float 的值不为 none

  3. overflow 的值不为 visible

  4. display 的值为 inline-block、table-cell、table-caption

  5. position 的值为 absolute、fixed

参考文献:

我对BFC的理解

BFC背后的原理

谈谈面试与面试题