您好,欢迎访问一九零五行业门户网

hasLayout与Block formatting contexts的学习(下)_html/css_WEB-ITnose

bfc布局规则:
内部的box会在垂直方向,一个接一个地放置。
box垂直方向的距离由margin决定。属于同一个bfc的两个相邻box的margin会发生重叠
每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
bfc的区域不会与float box重叠。
bfc就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
计算bfc的高度时,浮动元素也参与计算。
在css3中,对这个概念做了改动:http://www.w3.org/tr/css3-box/#block-level0
在css3中,将bfc 叫做 flow root。 简单示例:
1.自适应两栏布局
代码如下:
bfc

页面效果图:
上述示例,正好反映了bfc布局规则:每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
所以,sidebar虽然存在浮动,但main的左边依然与包含块的左边相接触。
2.bfc的区域不会与float box重叠。示例如下:
代码:
bfc

页面效果图:
通过overflow:hidden;触发main的bfc,main区域没有与float的sidebar重叠。说明了bfc的区域不会与float box重叠。
3.计算bfc的高度时,浮动元素也参与计算。
bfc

页面效果图:
我们通过
div.wrapper{ width:300px; border:2px solid #5dc2f6; overflow:hidden;}
overflow:hidden; 触发wrapper的bfc,
清除box的浮动带来的影响,得到的页面效果图如下:
因此说明:计算bfc的高度时,浮动元素也参与计算。
4.清除垂直边距重叠
代码:
bfc

页面效果图如下:
如图所示,box垂直方向的距离由margin决定。属于同一个bfc的两个相邻box的margin会发生重叠。所以,两个div的垂直距离变成了100px,而不是150px了。
如果我们给第二个div套上一层wrapper,并且触发外层的bfc,那么两个div就不是同一个bfc的两个相邻的box了,而是变成两个独立的bfc。
代码:
bfc

页面效果图如下:
垂直边距不再重叠,不是100px,而是150px了。
总结
以上事例都证明了:bfc就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。因为bfc内部的元素和外部的元素绝对不会互相影响,因此, 当bfc外部存在浮动时,它不应该影响bfc内部box的布局,所以bfc通过改变自己的宽度,实现不与浮动box有重叠。同样的,当bfc内部有浮动时,为了不影响外部元素的布局,bfc计算高度时会包括浮动的高度。避免margin重叠也是这样的一个道理。
haslayout与block formatting contexts的实例分析 一. 在触发 haslayout 的元素和创建了 block formatting contexts 的元素中,浮动元素参与高度的计算
情况1:没有创建 block formatting contexts 的块级非替换元素,触发了 ie 的 haslayout。
分析以下代码:
haslayout 和 bfc simple text in flow
float:left

container 没有创建 block formatting contexts。
container 的 'zoom:1'设置,是为了触发 ie 中的 haslayout;
container 的高度值为 auto,并且 'overflow' 的值为默认的 'visible';
span1是一个行内元素, div1 是一个处于普通流中的块元素;
div2 是一个浮动的块级元素。 根据 css2.1 规范第 10.6.3部分的高度计算规则,在进行普通流中的块级非替换元素的高度计算时,浮动子元素不参与计算。
所以,在进行 container 高度计算时,只受 span1 和 div1的影响,应该是它们两个的高度之和,所以最终container 的高度不包括div2的高度。
页面效果图在各浏览器的效果如下:
ie6 ie7:
ie8 firefox chrome safari opera:
当去掉container的zoom:1;各浏览器表现一致:
情况2:创建了 bfc的块级非替换元素,未触发 ie 的 haslayout。
代码如下:
haslayout 和 bfc simple text in flow
float:left

container 的 ‘overflow:hidden;’ 创建了bfc;
container 的 ‘overflow:hidden;’,在 ie6 中未触发 haslayout,但在 ie7中触发了 haslayout;
container 的高度值为 ‘auto’;
span1是一个行内元素,div1是一个处于普通流中的块元素;
div2是一个浮动的块级元素。 页面效果图如下:
ie6:
ie7/ie8/firefox/chrome/safari/opera
可见,只要 container 创建了 bfc,其浮动子元素就会参与其高度计算(ie7是由于触发了haslayout 导致与其它浏览器的效果相同)。
二.与浮动元素相邻的、触发了 haslayout 的元素或创建了 bfc 的元素,都不能与浮动元素相互覆盖。
与浮动元素相邻的、触发了 haslayout 的元素或创建了 block formatting contexts的元素,都不能与浮动元素相互覆盖。如果浮动元素的两侧有足够的空间放置该元素,则元素会紧邻浮动元素放置,必要时,该元素的宽度将会被压缩。否则它们可能会定位到浮动元素的下方。
情况1:没有创建bfc的块级非替换元素,触发了 ie 的 haslayout。
代码:
haslayout 和 bfc float block
怀才就象怀孕,时间久了会让人看出来。

ie6:
ie7/ie8
firefox/chrome/safari/opera
根据 css 2.1 9.5 floats 中的描述,浮动元素会覆盖普通流中的块容器。所以,div2 应该有一部分被 div1 覆盖。
情况2:创建了 bfc的块级非替换元素,未触发 ie 的 haslayout。
代码:
haslayout 和 bfc float block
怀才就象怀孕,时间久了会让人看出来。

firefox/chrome/safari/opera:
ie6:
ie7/ie8
div1 是一个浮动元素,背景是50%的透明
div2 的 ‘overflow:hidden;’ 在 ie6 中未触发 haslayout,但在 ie7 中触发了 haslayout。
根据 css 2.1 9.5 floats 中的描述,创建了bfc的元素不能与浮动元素重叠, 所以,div2 应该有一部分被 div1 覆盖。 三. 触发 haslayout 的元素和创建了 bfc的元素不会与它们的子元素发生外边距折叠
情况1:没有生成bfc的块级非替换元素,触发了 ie 的 haslayout。
代码:
haslayout和bfc

根据 css 2.1 8.3.1 collapsing margins 第一条,两个相邻的普通流中的块框在垂直位置的空白边会发生折叠现象。
通过zoom:1;在ie中触发了haslayout,所以,垂直边距不重叠,为150px。
而bfc未触发,所以垂直边距重叠,为100px;
ie6/ie7:
ie8/firefox/chrome/safari/opera:
情况2:生成 bfc的块级非替换元素,未触发 ie 的 haslayout。
代码:
bfc

ie6:
ie7/ie8/firefox/chrome/safari/opera:
ie7此时触发了haslayout,但ie6没有触发haslayout。
haslayout 和 bfc 的异同及可能产生的问题 区别
在 ie8之前的版本中,没有规范中提及的 block formatting contexts 和 inline formatting contexts概念,而是用 haslayout 来达到相似的目的。
在 ie 中可通过设置 ‘width’、’height’、’min-width’、’min-height’、’max-width’、’max-height’、 ‘zoom’、’writing-mode’ 来触发 haslayout,而这些特性值的设置不能够使元素创建 bfc。
在 ie 中很多元素默认就是拥有布局的,如 ipunt, button, select, textarea 等,但是这些元素在标准中会形成 inline formatting contexts。 共同点
两者都是决定了对内容如何定位及大小计算的规则。
两者都决定了与其他元素的相互作用的规则。
‘table-cell’ 和 ‘table-caption’ 既是 haslayout 的元素,又是可以创建 bfc 的元素。
浮动元素,绝对定位元素,inline-block 元素以及除 ‘visible’ 外任意值的 overflow(ie7) 在 ie 中可以触发 haslayout,同时在标准中,又可以创建bfc。 可能产生的兼容性问题:
由于 haslayout 和 bfc是对一类事物的不同理解,并且他们的启用条件不尽相同,因此如果一个元素设计时,在 ie 早期版本中触发了 haslayout ,但在其他浏览器中又没有创建bfc,或者相反,一个元素在 ie 早期版本中没有触发 haslayout ,在其他浏览器中却创建了 bfc(如设置了 ‘overflow:hidden’ ),将导致页面布局的重大差异。
解决方案
仅当一个元素即在 ie 早期版本中触发了 haslayout,又在其他浏览器中创建了bfc时,才能避免上述问题的发生。即同时启用上述两者以保证各浏览器的兼容,或者相反,两者皆不启用。 使元素即生成了bfc,又触发了 haslayout 对于触发 haslayout 的元素,通过 css 设置,使它产生bfc; 生成 bfc但是没有触发 haslayout 的元素,通过设置 ‘zoom:1’,使其触发 haslayout。 使元素即没有触发 haslayout,又没有创建 bfc。
如有错误或者不足的地方,还望指正!----妙瞳
文章参考资料:
http://w3help.org/zh-cn/causes/rm8002
其它类似信息

推荐信息