margin折叠的产生有几个条件:
垂直方向上毗邻的box不会发生折叠的情况:
折叠边距的计算
当两个margin都是正值的时候,取两者的最大值;当 margin 都是负值的时候,取的是其中绝对值较大的,然后,从 0 位置,负向位移;当有正有负的时候,先取出负 margin 中绝对值中最大的,然后,和正 margin 值中最大的 margin 相加。但必须注意,所有毗邻的margin要一起参与运算,不能分步进行。
以下内容转载自:http://www.smallni.com/haslayout-block-formatting-contexts/
‘Layout’ 是 IE 的专有概念,它决定了元素如何对其内容进行定位和尺寸计算,与其他元素的关系和相互作用,以及对应用还有使用者的影响。
1
2
3
4
5
6
7
|
< html >, < body > < table >, < tr >, < th >, < td > < img > < hr > < input >, < button >, < select >, < textarea >, < fieldset >, < legend > < iframe >, < embed >, < object >, < applet > < marquee > |
1
2
3
4
5
6
7
|
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*/ |
1
2
3
4
5
6
7
8
|
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(块格式化上下文)
1
2
3
4
|
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。
分析以下代码:
1
2
3
4
5
6
7
|
< 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。
分析以下代码:
1
2
3
4
5
6
7
|
< 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。
分析以下代码:
1
2
3
4
5
6
7
8
|
< div id = "Container" style="border:2px solid gold; width:300px; height:150px;<strong> background:url("grid2a.png") repeat;</ strong >"> < 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。
分析以下代码:
1
2
3
4
5
6
7
8
|
< div id = "Container" style="border:2px solid gold; width:300px; height:150px;<strong> background:url("grid2a.png") repeat;</ strong >"> < 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 > |
根据 CSS 2.1 9.5 Floats 中的描述,创建了BFC的元素不能与浮动元素重叠, 所以,DIV2 应该有一部分被 DIV1 覆盖。
这段代码在不同的浏览器环境中表现如下:( 注意 IE7(S) 此时触发了 hasLayout )
IE6 IE7(Q) IE8(Q) | IE7(S) IE8(S) Firefox Chrome Safari Opera |
---|---|
情况1:没有生成BFC的块级非替换元素,触发了 IE 的 hasLayout。
分析以下代码:
1
2
3
4
5
|
< div id = "Container" style = "width:300px; border:1px solid gold;" > < div id = "DIV1" style = "zoom:1; background:darkgray;" > < div id = "DIV2" style = "margin:30px 0; width:60px;" >content</ div > </ div > </ div > |
根据 CSS 2.1 8.3.1 Collapsing margins 第一条,两个相邻的普通流中的块框在垂直位置的空白边会发生折叠现象。
DIV1 和 DIV2 应该发生空白边折叠,深灰色的 DIV1 应该刚好包含 ‘content’ 文本。
这段代码在不同的浏览器环境中表现如下:
IE6 IE7 IE8(Q) | IE8(S) Firefox Chrome Safari Opera |
---|---|
可见,在 IE 中,触发 hasLayout 的元素,阻止了它自身与子元素间的空白边折叠。
情况2:生成 BFC的块级非替换元素,未触发 IE 的 hasLayout。
分析以下代码:
1
2
3
4
5
|
< div id = "Container" style = "width:300px; border:1px solid gold;" > < div id = "DIV1" style = "overflow:hidden; background:darkgray;" > < div id = "DIV2" style = "margin:30px 0; width:60px;" >content</ div > </ div > </ div > |
根据 CSS 2.1 8.3.1 Collapsing margins 第三条,生成BFC 的元素不会和在流中的子元素发生空白边折叠。
DIV1 和 DIV2 不应该发生空白边折叠,深灰色的 DIV1 应该撑满 Container 。
这段代码在不同的浏览器环境中表现如下:( 注意IE7(S) 此时触发了 hasLayout )
IE6 IE7(Q) IE8(Q) | IE7(S) IE8(S) Firefox Chrome Safari Opera |
---|---|
可见,在 IE 中,创建了 BFC,未触发 hasLayout 的元素,它自身与子元素间的空白边折叠还是会发生。
仅当一个元素即在 IE 早期版本中触发了 hasLayout,又在其他浏览器中创建了BFC时,才能避免上述问题的发生。即同时启用上述两者以保证各浏览器的兼容,或者相反,两者皆不启用。
margin折叠及hasLayout && Block Formatting Contexts
原文:http://www.cnblogs.com/shytong/p/5282526.html