# BFC 的定义
是 W3C CSS2.1 规范中的一个概念,它决定了元素如何对其元素进行定位,以及与其它元素的关系和相互作用。
在创建了 Block Formating Context 的元素中,其子元素会一个接一个地放置。垂直方向上他们的起点是一个包含块的顶部,两个相邻的元素之间的垂直距离取决于 margin 特性。在 Block Formating Context 中相邻的块级元素的垂直边距会折叠(collapse)。
在 Block Formating Context 中,每一个元素左外边距与包含块的左边相接触(对于从右到左的格式化,右外边接触右边),即使存在浮动也是如此(尽管一个元素的内容区域会由于浮动而压缩),除非这个元素也创建了一个 Block Formating Context。
# BFC到底是什么?
当涉及到可视化布局的时候,Block Formatting Context 提供了一个环境,HTML 元素在这个环境中按照一定规则进行布局。一个环境中的元素不会影响到其它环境中的布局。比如浮动元素会形成 BFC,浮动元素内部子元素的主要受该浮动元素影响,两个浮动元素之间是互不影响的。这里有点类似一个 BFC 就是一个独立的行政单位的意思。
# 怎样才能形成BFC
float
的值不为none
overflow
的值不为visible
display
的值为table-cell
,table-caption
,inline-block
中的任何一个position
的值不为relative
和static
# BFC 的作用
不和浮动元素重叠
如果一个浮动元素后面跟着一个非浮动的元素,那么就会产生一个覆盖的现象,很多自适应的两栏布局就是这么做的。比如下图的效果,参考例子 (opens new window)
清除元素内部浮动
只要把父元素设为BFC就可以清理子元素的浮动了,最常见的用法就是在父元素上设置
overflow: hidden
样式,对于 IE6 加上zoom:1
就可以了(IE Haslayout)嵌套元素 margin 边距折叠问题的解决
按照 BFC 的定义,只有同属于一个 BFC 时,两个元素才有可能发生垂直 margin 的重叠,这个包括相邻元素,嵌套元素,只要他们之间没有阻挡(例如边框,非空内容,padding等)就会发生 margin 重叠。
因此要解决 margin 重叠问题,只要让它们不在同一个 BFC 就行了,但是对于两个相邻元素来说,意义不大,没有必要给它们加个外壳,但是对于嵌套元素来说就很有必要了,只要把父元素设为 BFC 就可以了。这样子元素的 margin 就不会和父元素的 margin 发生重叠了。
# IE HasLayout
Layout 是一个 Internet Explorer for Windows 的私有概念,它决定了一个元素如何显示以及约束其包含的内容、如何与其他元素交互和建立联系、如何响应和传递应用程序事件、用户事件等。这种渲染特性可以通过某些 CSS 属性被不可逆转地触发。而有些 HTML 元素则默认就具有 layout。
一个元素“得到 layout”,或者说一个元素“拥有 layout” 的时候,是指它的微软专有属性 hasLayout 被设为了 true 。一个“layout 元素”可以是一个默认就拥有 layout 的元素或者是一个通过设置某些 CSS 属性得到 layout 的元素。
不同于标准属性,也不像某些浏览器的私有 CSS 属性,layout 无法通过某一个 CSS 声明直接设定 。也就是说没有“layout 属性”这么一个东西,元素要么本身自动拥有 layout,要么借助一些 CSS 声明悄悄地获得 layout。
下列元素应该是默认具有 layout 的:
<html>
,<body>
<table>
,<tr>
,<th>
,<td>
<img>
<hr>
<input>
,<button>
,<select>
,<textarea>
,<fieldset>
,<legend>
<iframe>
,<embed>
,<object>
,<applet>
<marquee>
下列 CSS 属性和取值将会让一个元素获得 layout:
position:
absolute
绝对定位元素的包含区块(containing block)就会经常在这一方面出问题。
float:
left
|right
由于 layout 元素的特性,浮动模型会有很多怪异的表现。
display:
inline-block
当一个内联级别的元素需要 layout 的时候往往就要用到它,这也可能也是这个 CSS 属性的唯一效果–让某个元素拥有 layout。
inline-block行为
在 IE 中是可以实现的,但是非常与众不同: IE/Win: inline-block and hasLayout 。width: 除
auto
外的任意值很多人遇到 layout 相关问题发生时,一般都会先尝试用这个来修复。
height: 除
auto
外的任意值height: 1% 就在 Holly Hack 中用到。
zoom: 除
normal
外的任意值IE专有属性。不过 zoom: 1 可以临时用做调试。
writing-mode:
tb-rl
MS专有属性。
IE7中引入的hasLayout成员
overflow:
hidden
|scroll
|auto
在 IE7 中,
overflow
也变成了一个 layout 触发器,这个属性在之前版本 IE 中没有触发 layout 的功能。position:
fixed
min-width: 任意值
就算设为0也可以让该元素获得 layout。
max-width: 除
none
之外的任意值min-height: 任意值
即使设为0也可以让该元素的 haslayout=true
max-height: 除
none
之外的任意值
# 参考资料
- 常规流( Normal flow ):http://www.w3help.org/zh-cn/kb/010/ (opens new window)