转自:http://www.smallni.com/haslayout-block-formatting-contexts/
因为本人脑子不好使,自己打印出了一张hasLayout和Block Formatting Contexts(以下简称BFC)的触发表贴在办公桌上(也可以称作创建了BFC),每天看看就记住了,不知道大家有没有对这2个东西做过深入了解,如果真的做过了解,一些各浏览器部分奇怪的BUG也会迎刃而解。今天,我们一起来剖析下,揭开它们神秘的面纱。
‘Layout’ 是 IE 的专有概念,它决定了元素如何对其内容进行定位和尺寸计算,与其他元素的关系和相互作用,以及对应用还有使用者的影响。
<html>, <body><table>, <tr>, <th>, <td><img><hr><input>, <button>, <select>, <textarea>, <fieldset>, <legend><iframe>, <embed>, <object>, <applet><marquee>
display: inline-block /*ALL*/height: (除 auto 外任何值) /*仅适用IE6 7*/width: (除 auto 外任何值) /*仅适用IE6 7*/float: (left 或 right) /*ALL*/position: absolute /*ALL*/writing-mode: tb-rl /*ALL*/zoom: (除 normal 外任意值) /*仅适用IE6 7*/
min-height: (任意值)/*以下适用IE7+*/min-width: (任意值)max-height: (除 none 外任意值)max-width: (除 none 外任意值)overflow: (除 visible 外任意值,仅用于块级元素)overflow-x: (除 visible 外任意值,仅用于块级元素)overflow-y: (除 visible 外任意值,仅用于块级元素)position: fixed
IE有它自己的hasLayout属性,那么非IE浏览器呢?非IE浏览器采用的就是BFC(块格式化上下文)
float:(任何值除了none)overflow:(任何值除了visible)display:(table-cell/table-caption/inline-block)position:(任何值除了static/relative)
Tips:我们有时会用overflow:hidden的方法去清除浮动,就是因为触发了元素的块格式化上下文(IE6 7要申明zoom为1),这个方法的确简单,但很暴力 – -#
情况1:没有创建 BFC的块级非替换元素,触发了 IE 的 hasLayout。
分析以下代码:
<div style="width:300px;"> <div id="Container" style="background:silver; zoom:1;"> <span id="SPAN1" style="background:gray;">simple text</span> <div id="DIV1" style="width:150px; height:50px; background:dimgray;">in flow</div> <div id="DIV2" style="float:left; background:gold;">float:left</div> </div></div>
根据 CSS2.1 规范第10.6.3部分的高度计算规则,在进行普通流中的块级非替换元素的高度计算时,浮动子元素不参与计算。
所以,在进行Container高度计算时,只受SPAN1和DIV1的影响,应该是它们两个的高度之和,所以最终银色部分不应该包含金色的部分。
这段代码在不同的浏览器环境中表现如下:
IE6 IE7 IE8(Q) | IE8(S) Firefox Chrome Safari Opera |
---|---|
去掉Container的 ‘zoom:1′ 后,各浏览器表现一致:
可见,IE 浏览器中,触发 hasLayout 的元素在进行高度计算的时候,其浮动的子元素也会参与运算。
情况2:创建了 BFC的块级非替换元素,未触发 IE 的 hasLayout。
分析以下代码:
<div style="width:300px;"> <div id="Container" style="background:silver; overflow:hidden;"> <span id="SPAN1" style="background:gray;">simple text</span> <div id="DIV1" style="width:150px; height:50px; background:dimgray;">in flow</div> <div id="DIV2" style="float:left; background:gold;">float:left</div> </div></div>
根据 CSS2.1 规范第10.6.7部分的高度计算规则,在计算生成了 BFC的元素的高度时,其浮动子元素应该参与计算。
所以,在进行Container高度计算时,DIV2也应该参与计算,所以最终银色部分应该包含金色的部分。
这段代码在不同的浏览器环境中表现如下:( 注意 IE7(S) 此时触发了 hasLayout )
IE6 IE7(Q) IE8(Q) | IE7(S) IE8(S) Firefox Chrome Safari Opera |
---|---|
可见,只要Container创建了 BFC,其浮动子元素就会参与其高度计算(IE7(S) 是由于 hasLayout 导致与其他浏览器的效果相同)。
如果浮动元素的两侧有足够的空间放置该元素,则元素会紧邻浮动元素放置,必要时,该元素的宽度将会被压缩。否则它们可 能会定位到浮动元素的下方。
情况1:没有创建 BFC 的块级非替换元素,触发了 IE 的 hasLayout。
分析以下代码:
<div id="Container" style="border:2px solid gold; width:300px; height:150px; background:url("grid2a.png") repeat;"> <div id="DIV1" style=" width:100px; height:100px; float:left; filter:alpha(opacity=50); opacity: 0.5;"> Float Block </div> <div id="DIV2" style=" zoom:1;"> If I had a single flower for every time I think about you, I could walk forever in my garden. </div></div>
其中,grid2a.png背景是 100px * 100px 的图片:
根据 CSS 2.1 9.5 Floats 中的描述,浮动元素会覆盖普通流中的块容器。所以,DIV2 应该有一部分呢被 DIV1 覆盖。
这段代码在不同的浏览器环境中表现如下:(忽略 IE 中 3px BUG 的影响)
IE6 IE7 IE8(Q) | IE8(S) Firefox Chrome Safari Opera |
---|---|
情况2:创建了 BFC的块级非替换元素,未触发 IE 的 hasLayout。
分析以下代码:
<div id="Container" style="border:2px solid gold; width:300px; height:150px; background:url("grid2a.png") repeat;"> <div id="DIV1" style=" width:100px; height:100px; float:left; filter:alpha(opacity=50); opacity: 0.5;"> Float Block </div> <div id="DIV2" style=" overflow:hidden;"> If I had a single flower for every time I think about you, I could walk forever in my garden. </div></div>
新闻热点
疑难解答