其实对 BFC(Block Formatting Contexts 块级格式化上下文) 听过很多次了,虽然每次都无意中也有用到,但是并没有深入的看看这个到底是个什么东西。今天有点时间看到了这篇文章,但是感觉理解起来有点吃力,所以总结下,按照自己的理解再写一写,一方面加深记忆,一方面,以后自己理解起来也方便。

1. 防止外边距叠加。
这里的防止外边距叠加不是两个同级(兄弟)元素之间的外边距叠加,而是防止父元素和子元素之间的外边距叠加。来个结构:

  <div class="a"></div>
  <div class="a">
    <div class="b"></div>
    <div class="b"></div>
  </div>

然后样式:

  .a, .b {
    margin:10px 0;
  }
  .a {
    width:200px;
    height:50px;
    background:red;
  }
 .b {
    width:100px;
    height:10px;
    background:blue;
  }

此时给 .a .b 都有一个

  margin:10px 0;

的外边距。但是并没有触发 .b 的 BFC 特性,此时如图所示:

对 BFC (Block Formatting Contexts) 的一点理解
例子请看:http://jsbin.com/odesoz/3/

然后给 .a 添加

  overflow:hidden;

以触发 .a 的 BFC 特性,此时结果如图所示:

对 BFC (Block Formatting Contexts) 的一点理解
红色是 .a ,蓝色是 .b ,且 .b(蓝色) 是 .a(红色) 的子元素,一目了然。
此时的例子请看:http://jsbin.com/odesoz/2/

2. 清除浮动
其实平常我们使用的清除浮动的技巧,也就是利用了 BFC 的原理。
浮动元素导致父级元素的高度塌陷,此时触发父级元素的 BFC,因为

创建了 BFC的元素就是一个独立的盒子,里面的子元素不会在布局上影响外面的元素,反之亦然,同时BFC任然属于文档中的普通流。

其实这句话挺不好理解的,按我的理解,就是这个元素触发了 BFC 然后它就需要按它的行为来,不管里面的元素是什么样子的。不管你浮动不浮动,我多大我就是多大。所以讲浮动闭合(清除)了。
到这里,其实另一点也就呼之欲出了,那是什么呢?就是 只要是可以使父级元素触发 BFC 的特性,都可以闭合浮动。这些就是闭合浮动的原理。(参考

例子可看:http://jsbin.com/odesoz/5/(清除浮动), http://jsbin.com/odesoz/7/ (未清除浮动)

3. 块级格式化上下文不会重叠浮动元素
其实也就是如果有浮动元素和 BFC 一起的话,BFC 元素,会表现为有宽高的样子。具体请看这篇文章的 3.3,因为我觉得这里写的会比我写得好。而且配图也不错。

那么到底神马是 BFC 呢? (其实这些不想写来着,网上那么多,但还是加深印象吧)

其实说的简单点,就类似于在一个环境中的好几个 display:block 的元素所产生的相互影响的原理和表现。

比较专业的说法就是:它能把一个集合中的 float, margin, clear 等等的各种元素包裹,形成的一个集合就为 BFC , BFC 中的任何都不会对 BFC 外的元素产生影响。
通俗地来说:创建了 BFC 的元素就是一个独立的盒子,里面的子元素不会在布局上影响外面的元素,反之亦然,同时 BFC 仍然属于文档中的普通流。
在普通流( Normal flow )中,在创建了块格式化上下文的元素中的子元素都会按照块格式化上下文提供的规矩来排列自己,除非自己也创建一个新的块格式化上下文。

如何触发块级格式化上下文(BFC)?

    float:left|right ,除了none
    overflow:hidden|auto|scroll(也就是除了overflow:visible;)
    position: absolute|fixed
    display:inline-block|table-cell|table
    fieldset 元素
    表格的单元格(display: table-cells,TD、TH)
    表格的标题(display: table-captions,CAPTION)
    表格元素创建的 “匿名框” 。(display:table 之后创建的匿名框 http://www.w3.org/TR/CSS21/tables.html#anonymous-boxes)

虽然 IE6 7 不支持 BFC,但是在他们中有一个类似的概念 hasLayout。触发hasLayout的条件:

    position: absolute 
    float: left|right 
    display: inline-block 
    width: 除 “auto” 外的任意值 
    height: 除 “auto” 外的任意值 (例如很多人清除浮动会用到 height: 1%  ) 
    zoom: 除 “normal” 外的任意值 (MSDN)
    writing-mode: tb-rl (MSDN)
  在 IE7 中,overflow 也变成了一个 layout 触发器:
    min-width:任何值
    min-height:任何值
    max-width:除了none之外的任何值
    max-height:除了none之外的任何值
    overflow: hidden|scroll|auto ( 这个属性在IE之前版本中没有触发 layout 的功能。 )
    overflow-x|-y: hidden|scroll|auto (CSS3 盒模型中的属性,尚未得到浏览器的广泛支持。他们在之前IE版本中同样没有触发 layout 的功能)

其他一些知识点,请参考引用文章中的那几篇引用文章。