May08

z-index下的一些知识

分类: Html/CSS | 转载请注明: 出自 海玉的博客
本文地址: http://www.hicss.net/some-z-index-knowledge/

前几天工作的时候遇到一个问题,在IE6下select 这个控件似乎无法用z-index 属性隐藏,接下来就开始了寻找问题的解法,总结了一些z-index 的知识。

z-index 定义和用法

z-index 属性设置元素的堆叠顺序。拥有更高堆叠顺序的元素总是会处于堆叠顺序较低的元素的前面。该属性设置一个定位元素沿z 轴的位置,z 轴定义为垂直延伸到显示区的轴。如果为正数,则离用户更近,为负数则表示离用户更远。——W3shcool

z-index:auto | number

默认值:auto 堆叠顺序与父元素相等

number:无单位的整数值,可为负数

JavaScript 语法: object.style.zIndex=”1″

注意:z-index 属性适用于那些被定义了除position:static 外任意属性的元素中。即z-index 仅能在定位元素上奏效(position: absolute | relative | fix)。

stacking context & stack level & z-index 是什么

stacking context 堆叠上下文

每个定位元素都归属于一个stacking context(即堆叠上下文,以下统一用堆叠上下文),最初的堆叠上下文(即根部堆叠上下文)是由根元素产生(一般页面的根元素是body),而其他的堆叠上下文则由定位元素产生(此定位元素的z-index 被定义一个非auto 的z-index 值),定位子元素会以这个基准堆叠上下文为参考,用相同的规则来决定层叠顺序。

触发stacking context

1. 定位元素并且定义了z-index为非auto;

2. FF, Safari, Chrome下元素设置opacity属性(1除外)会产生stacking context;(除了Opera)

3. IE6,7下的定位元素,无论设置了z-index,或无论z-index设置成什么值,都会产生新的 stacking context。

stack level 堆叠级别

在一个堆叠上下文中的每个box ,都有一个stack level(即堆叠级别,以下统一用堆叠级别),它决定着在同一堆叠上下文中每个box 在z 轴上的显示顺序。同一堆叠上下文中,堆叠级别值大的显示在上,堆叠级别值小的显示在下,同一堆叠级别遵循后来居上的原则(back-to-front )。不同堆叠上下文中,子元素显示顺序以父级的堆叠上下文的堆叠级别来决定显示的先后情况。于自身堆叠级别无关。说白了就是父元素的堆叠上下文的堆叠级别决定了子元素堆叠级别将来的发展,父元素堆叠级别低,则子元素堆叠级别就必然比父元素堆叠级别高的子元素堆叠级别低,即使这个子元素在他父元素内部的堆叠级别再高也无济于事。

z-index

页面中元素在z轴方向上的排列,先由堆叠上下文决定,如果是相同的堆叠上下文那么由堆叠级别决定(后来居上原则),如果又是相同的堆叠级别(同一个父元素),则由z-index 决定。

这里最容易搞混的就是堆叠级别和z-index ,大多数时候觉得他们是同一个东西,而事实上他们还是有区别的,个人认为,当没有z-index 时候,我们所依靠的准则是以堆叠级别的后来居上的原则来判定顺序。如果在一个堆叠上下文,一般就是在body 下,俩个不同的z-index 的时候,以z-index 大小来判定上下顺序,而我们平时印象里留意的最多的就是z-index ,所以往往误解了堆叠级别和z-index 的区别。

z-index 浏览器兼容问题

在FF和IE下查看如下代码:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>z-index 浏览器兼容问题</title>
<style>
.wrap1{position:relative;}
.inner1{width:200px; height:200px; background:#fcc; position:absolute; top:100px; left:200px; z-index:300;}
.wrap2{width:200px; height:200px; background:#cfc; position:absolute; top:50px; left:150px; z-index:100;}
</style>
</head>

<body>
  <div class="wrap1">
    <div class="inner1">这里是wrap1 这个box应该在上面</div>
  </div>
  <div class="wrap2">
      这里是wrap2 这个box应该在下面,IE浏览器会对定位元素产生一个新的stacking context ,甚至当元素 z-index的为“auto”。
  </div>
</body>
</html>

只有定位元素的z-index 被定义一个非auto 的z-index 值才能产生新的stacking context。而例子中wrap1 元素并没有定义 z-index,即z-index 为默认值auto 。所以按理他不会影响子元素的层叠顺序。即背景色为红色的wrap1 和背景色为绿色的 wrap2 的stacking context 相同,即都为根元素产生的root stacking context。再根据规则中当stacking context 一样的时候,就用z-index 的值来决定怎样显示的原理,则应该z-index 属性值300的.inner1 在 z-index 属性值100wrap2之上。我们在Firefox 和IE 中分别测试最终的效果,会发现Firefox 中显示的效果和上面分析的效果是完全一致的,而IE 中的显示却不一致。

原因:其实这是IE 浏览器(windows)的一个BUG ——在IE 浏览器中,定位元素会产生一个新的stacking context,并且从z-index 的值为0开始。ie 中给元素设置position 属性(static除外)可产生新的stacking context。

ff中给元素设置opacity属性(1除外)可产生新的stacking context

除此之外只有定位元素设置了z-index(auto除外)才会产生新的stacking context,子元素将按照新的stacking context,定位。

参考文章:《元素层叠级别(stack level)及z-index剖析》

1 个评论

  1. 嗯。。。在 Opera and Opera Mini 下面 opacity<1 貌似也会产生 stacking context,但是在 IE (9 or 10) 下不会。W3C 的标准是应该产生新的 stacking context 这时。

发表评论