首先我们看看 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).
浮动元素和绝对定位元素,非块级盒子的块级容器(例如 inline-blocks、table-cells 和 table-captions),以及 overflow 值不为 visiable 的块级盒子,都会为他们的内容创建新的块级格式化上下文。
在一个块级格式化上下文里,盒子从包含块的顶端开始垂直地一个接一个地排列,两个盒子之间的垂直的间隙是由他们的margin 值所决定的。两个相邻的块级盒子的垂直外边距会发生叠加。
在块级格式化上下文中,每一个盒子的左外边缘(margin-left)会触碰到容器的左边缘(border-left)(对于从右到左的格式来说,则触碰到右边缘),即使存在浮动也是如此,除非这个盒子创建一个新的块级格式化上下文。
从上面我们还可找出几个几个比较重要的概念东西,比如:boxe , block formatting context。毫无疑问 BFC 就是 block formatting context 的缩写,中文就是 块级格式化上下文 的意思。我们在那个 w3c 那个页面发现还有其他 inline formatting context,所以我们可以看看 formatting context 是个什么东西:
Formatting context 是 W3C CSS 2.1 规范中的一个概念。它是页面中的一块渲染区域,并且有一套渲染规则,它决定了其子元素将如何定位,以及和其他元素的关系和相互作用。
最常见的 Formatting context 有 Block fomatting context(简称 BFC)和 Inline formatting context(简称 IFC)。CSS2.1 中只有 BFC 和 IFC,CSS3 中还增加了 GFC 和 FFC。
至于那个 box 还要讲吗?嗯,还是回顾一下:
Box 是 CSS 布局的对象和基本单位, 直观点来说,就是一个页面是由很多个 Box(即 boxes)组成的。元素的类型和 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。
这里我们也通俗的理解一下:
BFC 就是 块级格式化上下文 的意思,创建了 BFC 的元素就是一个独立的盒子,不过只有 Block-level box 可以参与创建 BFC, 它规定了内部的 Block-level Box 如何布局,并且与这个独立盒子里的布局不受外部影响,当然它也不会影响到外面的元素。
BFC 有一下特性:
1. 内部的 Box 会在垂直方向,从顶部开始一个接一个地放置。
2. Box 垂直方向的距离由 margin 决定。属于同一个 BFC 的两个相邻 Box 的 margin 会发生叠加
3. 每个元素的 margin box 的左边, 与包含块 border box 的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
4. BFC 的区域不会与 float box 叠加。
5. BFC 就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之亦然。
6. 计算 BFC 的高度时,浮动元素也参与计算。
到最后我就是考虑 How 了,不用说你也知道了,就是怎么解决这些问题,这些知识点该怎么用,还有没有其他的方法..
那么我们该怎么使用 BFC 呢,如何触发 BFC 呢?
在以上的情况里可以创建 BFC。
接下我们看下怎么运用 BFC,在哪些场景可以用到 BFC。
三P每个 p 之间的距离为 50px,发生了外边距叠加。 要解决这个叠加问题即让每个 P 之间是 100px,我们可以新建一个 BFC,怎么建呢?可以给 p 元素添加一个父元素,让它触发 BFC。
从图中我们会发现上面 BFC 的第三个特性,就是元素的左外边距会触碰到包含块容器的做外边框,就算存在浮动也会如此。那么我们如何解决这个问题呢?看上面BFC第四个特性,就是 BFC 不会与浮动盒子叠加,那么我们是不是可以创建一个新的 BFC 来解决这个问题呢?来看看: 发现我们用 overflow:hidden 触发 main 元素的 BFC 之后,效果立马出现了,一个两栏布局就这么妥妥的搞定!
因为上面第六个特性提到计算 BFC 高度时,浮动元素也会参与计算,我们先看一个例子: 我们发现由于里面两个子元素浮动的关系,两个 box 已经脱离了父元素的包含块,父元素高度已经塌陷,我们需要让父元素包含两个box子元素,这样计算高度时,两个浮动子元素就会参与,所以我们要闭合浮动,触发父元素的BFC。
当然清理(闭合)浮动还有很多方法,大家可以看看一丝大神写的那些年我们一起清除过的浮动。 好了写到这里基本才不多了,BFC 是个很奇怪的东西,她一直隐式的存在我们的 CSS 样式里,但是我们要记住 BFC 是页面元素里一个独立存在作用块,它不影响它外面的布局,外面的元素也不会影响到 BFC 里面的布局。

