1 min read

IE6、7下的 z-index 问题

一般在使用 z-index 时,哪怕我们不十分清楚 z-index 概念,也很少会碰上问题。

但 IE6、7 对 z-index 层叠上下文(stacking context) 生成条件有点误会,会对现实应用造成困扰,也就是常见的 z-index 失效问题。

看一个别人的 demo。Demo 中,IE6、7 下, position:relative 也生成一个上下文。而根据 W3C 规范,这是错误的。

且按照 IE6、7 的错误理解,来分析下 z-index 是怎么比较大小的。

Demo 的 HTML 代码如下:

<div id="container">
    <div id="box1">This box should be on top</div>
</div>

<div id="box2">This box should not be on top; IE however seems to create a new stacking context for positioned elements, even when the computed z-index of that element is 'auto'.</div>

CSS 代码:

#container {
    position: relative;
}
#box1 {
    background-color: yellow;
    height: 200px;
    left: 510px;
    position: absolute;
    top: 100px;
    width: 200px;
    z-index: 20;
}
#box2 {
    background-color: lime;
    height: 200px;
    left: 460px;
    position: absolute;
    top: 50px;
    width: 200px;
    z-index: 10;
}

现代浏览器下 z-index 值比较

在现代浏览器中,绝对定位的 #box1 与 #box2 元素均参照初始包含块比较 z-index 值,假定初始包含块 z-index 值为0:

#box1 #box2
html
自身 20 10

如果我们也按 CSS 规则的权重排列来理解上面的值:

#box1 - 0,20
#box2 - 0,10

显然,#box1 要排在 #box2 上面,即黄色块在绿色块上。

IE6、7下 z-index 值比较

因为 position:relative 也生成了一个上下文,于是上面的表格会变成:

#box1 #box2
html
#container
自身 20 10

对比如下:

#box1 - 0,0,20
#box2 - 0,10

这样,#box2 变成在 #box1 上面。

解决办法是给 #container 元素设置一个大于10的 z-index 值:

#box1 - 0,11,20
#box2 - 0,10

你可能想问设置为10为什么不行,因为同一个 z-index 值,后绘制的与之前的内容如果有交叉区域,则会覆盖之前的内容 – 这是我的理解。

调试、解决

当给一个元素设置 z-index:9999 时,IE6、7 下元素层叠还是无效,则可以按上面所描述的,从初始包含块开始,找出所有层叠上下文,然后对比 z-index 值。一旦 z-index 链路明确,也就知道该在哪个节点下手。

报告问题 修订

如果你有自建 https 代理的需求,欢迎尝试 Phantom,一键搭建,方便快捷。查看 demo