一. w3c规范中的BFC定义:

“浮动元素和绝对定位元素,非块级盒子的块级容器(例如 inline-blocks, table-cells, 和 table-captions),以及overflow值不为“visiable”的块级盒子,都会为他们的内容创建新的BFC(块级格式上下文)。

在BFC中,盒子从顶端开始垂直地一个接一个地排列,两个盒子之间的垂直的间隙是由他们的margin 值所决定的。在一个BFC中,两个相邻的块级盒子的垂直外边距会产生折叠。 在BFC中,每一个盒子的左外边缘(margin-left)会触碰到容器的左边缘(border-left)(对于从右到左的格式来说,则触碰到右边缘)。

也就是说BFC中的元素的布局是不受外界的影响(我们往往利用这个特性来消除浮动元素对其非浮动的兄弟元素和其子元素带来的影响)。并且在一个BFC中,块盒与行盒(行盒由一行中所有的内联元素所组成)都会垂直的沿着其父元素的边框排列。 由这段定义,我们可以得出:

1. 哪些元素会生成BFC:

1.根元素(整个页面就是一个大的BFC);
2.float为 left | right;
3.overflow为 hidden | auto | scroll;
4.display为 inline-block | table-cell | table-caption | flex | inline-flex;
5.position为 absolute | fixed;

2. BFC的布局规则:

1.每一个BFC盒子会在垂直方向一个接一个地排列;
2.两个BFC盒子之间的垂直的间隙是由他们的margin 值所决定的。属于同一个BFC的两个相邻盒子的垂直方向的margin会重叠;

3.每一个BFC盒子的左外边缘(margin-left)会触碰到容器的左边缘(border-left)(对于从右到左的格式来说,则触碰到右边缘); 4.计算BFC的高度时,浮动元素也参与计算;
5.不与外部浮动元素重叠;
6.BFC就是页面上的一个隔离的独立容器,容器里面的子元素与容器外部元素不会相互影响;

二. BFC的应用实例

1. 自适应两栏布局

2. 清除内部浮动

3. 防止垂直margin重叠

在CSS当中,相邻的两个盒子(可能是兄弟关系也可能是祖先关系)的外边距可以结合成一个单独的外边距。这种合并外边距的方式被称为折叠,并且因而所结合成的外边距称为折叠外边距。

折叠的结果:

  1. 两个相邻的外边距都是正数时,折叠结果是它们两者之间较大的值;
  2. 两个相邻的外边距都是负数时,折叠结果是两者绝对值的较大值;
  3. 两个外边距一正一负时,折叠结果是两者的相加的和;

产生折叠的必备条件:

  1. margin必须是邻接的,没有padding和border将他们分隔开;
  2. 必须是处于常规文档流(非float和绝对定位)的块级元素,并且处于同一个BFC当中;

产生折叠的常见情况:

  1. 元素的margin-top与其第一个常规文档流的子元素的margin-top;
  2. 元素的margin-bottom与其下一个常规文档流的兄弟元素的margin-top;
  3. height为auto的元素的margin-bottom与其最后一个常规文档流的子元素的margin-bottom;
  4. 高度为0且不包含常规文档流的子元素,并且自身没有建立新的BFC的元素的margin-top和margin-bottom;

浮动和绝对定位不与任何元素产生 margin 折叠:

原因:浮动元素和绝对定位元素不与其他盒子产生外边距折叠是因为元素会脱离当前的文档流,违反了上面所述的两个margin是邻接的条件同时,又因为浮动和绝对定位会使元素为它的内容创建新的BFC,因此该元素和子元素所处的BFC是不相同的,因此也不会产生margin的折叠;

因此可以通过使元素成为BFC而避免margin折叠。BFC提供了一个独立布局的环境,每个BFC都遵守同一套布局规则。例如,在同一个BFC内,盒子会一个挨着一个的排,相邻盒子的间距是由margin决定且垂直方向的margin会重叠。而float和clear float也只对同一个BFC内的元素有效;

总结

其实以上的几个例子都体现了BFC布局规则第六条: BFC就是页面上的一个隔离的独立容器,容器里面的子元素与容器外部元素不会相互影响。
因此, 当BFC外部存在浮动时,外部元素不会影响BFC内部的布局,BFC会通过变窄,而不与浮动有重叠;同样的,当BFC内部有浮动时,为了不影响外部元素的布局,BFC计算高度时会包括浮动的高度和margin值,因此可以避免margin重叠和闭合浮动。

本文作者:子匠_Zijor,转载请注明出处:http://www.dengzhr.com/frontend/css/267