IE 6 7 下子元素的margin-top为什么会传递给父元素?

Refresh
  • 154

请输入图片描述

<div id="parent">
    <div id="id1">test</div>
</div>
 #parent { 
            position: relative;
            width: 200px;
            height: 200px;
            padding: 10px;
            border: 10px solid red;
            margin: 20px;
            background-color: yellow;
        }
#id1 {
            width: 100px;
            height: 100px;
            padding: 10px;
            border: 10px solid #000;
            margin: 10px;

            background-color: blue;
}
var oDiv = document.getElementById('id1');
alert(oDiv.offsetWidth);
alert('offsetLeft:' + oDiv.offsetLeft);
alert('offsetTop:' + oDiv.offsetTop);
offsetWidth:140
offsetLeft:20
offsetTop:10/20 IE6 7 值为10 其他为20 

http://jsfiddle.net/x7DY3/1/

回复
阅读 3.4k
2 个回答
Humphry
  • 16.4k
✓ 已被采纳

兼容性1:浏览器默认样式

IE6/7的body之上默认有margin(body { margin: 15px 10px; },同时和其他浏览器不太一样(一般是margin: 8px),见这里)。

这其中差了14px,用例看上去像是发生了margin-top传递,但实则不是。
(如果我没有记错,margin传递一般发生在inline-block中,它可以给把自己的margin-top传递给它的包含块)

我在用例中多做了一个reset:html, body { margin: 0; padding: 0 ; }。测试表明,在各个浏览器中,父元素的margin-top是一致的。见:http://jsfiddle.net/x7DY3/15/show

兼容性2:padding-top和margin折叠的布局bug

另外一个问题是:IE6/7下,#parent之上的padding-top设置的表现就像是和子元素的margin-top折叠了一样。

可以做一个实验查看问题的表现:增大父容器的padding-top/增大子元素的margin-top。

见:http://jsfiddle.net/x7DY3/21/show/

我掌握的资料中(W3CHelp,wiki,知识库)没有查到根本原因。
实际使用中,父子元素同时通过padding/margin表达留白的需求很罕见(常见方案1:父元素overflow:hidden; *zoom: 1,子元素margin;常见方案2,父元素padding),这里暂不深究了。


对于offsetTop的兼容性,quirksmode给出一个结论在此

When calculating offsetTop, IE5-7 does not count elements with position: relative as offsetParents, and moves on to the next offsetParent in the chain. offsetLeft is calculated correctly.

但就我们这个用例来说,这个CSSOM并没有按照它所说的,offsetTop计算基于body(用例中的next offsetParent,也就是body)的偏差。
由于这个CSSOM忠实地反映了布局上的bug,问题还是出在布局上。

P.S. 对于offsetTop和offsetLeft值,IE8返回的是30px。

King
  • 1.5k
alert('offsetTop:' + oDiv.offsetTop);

offsetTop弹出来的是子元素顶端到父元素顶端的距离,也不全是margin-top,还包括了父元素的pandding

请输入图片描述
这些值每个浏览器都多少有些差异的
坐等大神回答

宣传栏