1、负边距 (margin) 导致元素溢出 hasLayout 容器时显示异常
如下代码:
结果在各种浏览器显示如下:123
根据W3C CSS2.1规范,当给一个块级元素设置了负值的 'margin' ,如果该元素的父容器 'overflow' 为 'visible' ( 'overflow' 的默认值就是 'visible' ),这个块级元素可能会由于负值的 'margin' 而使其父容器无法全容纳其自身,其会部分“溢出”父容器并在父容器之外被渲染,然而:
- 在 IE6 IE7(Q) IE8(Q) 下,由于负值的 'margin' 导致子元素 DIV 超出其父容器部分,均被父元素隐藏,而其 'margin-bottom' 由于没有超出父容器则被显示出来。
- 在 IE7(S) 下情况比较特殊, 'margin-top' 与 'margin-right' 与 IE6 中一样,超出父容器的部分被父容器隐藏。而 'margin-bottom' 虽然并没有因为其负值而超出父容器,但浏览器却将子元素 DIV 的内部裁去了5px。而 'margin-left' 则没有因为负值的影响而被父容器隐藏,反而显示了出来。
在确保元素的容器触发 hasLayout 的前提下,为该元素同时设置 'position:relative' 和 'zoom:1'。
首先需要保证容器在IE中触发 hasLayout 属性,可以通过zoom:1实现。
在 IE7(S) 中,当使设置了负值 'margin' 的元素的 hasLayout 属性为 'true' ,即触发该元素的 hasLayout 特性后,此 Bug 现象消失,例如为该元素设置宽度或高度,或者在完全不影响该元素盒模型的情况下使用 zoom:1 来触发 hasLayout 从而消除此 Bug 。
在 IE6 IE7(Q) IE8(Q) 中,仅仅触发 hasLayout 特性并不一定能消除此 Bug ,同时还需要为该元素设置 'position:relative',即在完全不影响该元素盒模型的情况下使用 zoom:1 'position:relative' 。
2、IE6 IE7 IE8(Q) 中浮动元素和绝对定位元素某些情况下会影响普通流中毗邻 'margin' 的折叠
在CSS 2.1中,- 普通流中两个或多个块框相邻的垂直 'margin' 会折叠。
- 浮动框和其它框之间的垂直 'margin' 不折叠(浮动框与浮动框内的浮动框 'margin' 不折叠)。
- 绝对定位框之间 'margin' 不折叠(绝对定位框与绝对定位框内的绝对定位框 'margin' 不折叠)。
2.1、普通流中子元素和父元素毗邻 'margin' 的折叠
分析以下代码:
根据 CSS2.1 规范中的描述可知, DIV 和 container 会发生 'margin' 折叠。abovecontentbelow
结果在各种浏览器显示如下:
可见,在 IE6 IE7 IE8(Q) 中,浮动元素会阻止普通流中毗邻的父子 'margin' 的折叠。
2.2、在 IE 中绝对定位元素可能阻止父子元素相邻 'margin' 的折叠
如下代码:
根据 CSS2.1 规范中的描述可知, DIV 和 container 会发生 'margin' 折叠。abovecontentbelow
结果在各种浏览器显示如下:
2.3、普通流中兄弟节点毗邻 'margin' 的折叠
在 IE6 IE7(Q) IE8(Q) 中,浮动元素可能会阻止普通流中毗邻 'margin' 的折叠。
如下代码:
根据 W3C 标准, DIV1 和 DIV2 应该发生 'margin' 折叠,因为它们会认为不在普通流中的 Float 不存在。aboveFloatbelow
结果在各种浏览器显示如下:
可见,在 IE6 IE7(Q) IE8(Q) 中, 'margin' 毗邻的兄弟节点之间的浮动元素可能会阻止它们的 'margin' 折叠。
解决方法:1. 根据具体需求,调整 'margin' 的位置和大小; 2. 使用 CSS hack 设置 IE 中的 'margin' 大小,以避免 IE 跟其他浏览器的布局差异。
3、IE6 IE7 IE8(Q) 中父元素带有 hasLayout 时,其左浮动子元素果存在带有非零值的 margin-bottom 时,则该子元素的 margin-bottom 设置失效;
如下代码:
content_text content_text结果在各种浏览器显示如下:
可见,在 IE6 IE7 IE8(Q)中,容器 DIV 的 'zoom:1' 触发了 hasLayout,其内部浮动子元素也参与到了容器的高度计算之中。但是浮动子元素设置的 'margin-bottom' 消失;在其他浏览器中,其内部浮动子元素也参与到了容器的高度计算之中。浮动子元素的四个方向的 margin 均正常。
解决方法:为容器显式地设置高度。若容器高度不定,则要避免在触发了 hasLayout 的容器内的浮动子元素上设置 'margin-bottom' 特性,可以通过为容器设置 'padding-bottom' 达到相似的效果。
只要不同时触发父元素hasLayout、子元素左浮动、左浮动子元素拥有非零的 margin-bottom 值,这三个条件中任意一项,均可解决此问题。