首页 > 代码库 > CSS z-index属性

CSS z-index属性

  利用z-index,可以改变元素相互覆盖的顺序,有较高z-index值的元素比z-index值较低的元素离读者更近。也就是说有较高z-index值的元素会覆盖其他元素。

   如果不对节点设定position属性,位于文档流后面的节点会覆盖前面的节点。比如

<div id="a">a</div><div id="b">b</div>

  

  

 

 

   如果将position设为relative,absolute或者fixed,这样节点会覆盖没有设置position属性值或者属性值为static的节点

<div id="a">a</div><div id="b" style="position:relative">b</div>

   如果所有节点都定义了position的值且值都不为static,并且未指定z-index值,那么文档流后面的依然要覆盖前面的

<div id="a" style="position:absolute;top:0;">a</div><div id="b" style="position:absolute;top:0;">b</div>

  由①②③可知,正常情况下即没有设定z-index值时,文档流后面的节点比文档流前面的节点层级高,设定了position的值(relative/absolute/fixed)的节点比没有设定position值或者值为static的节点层级高。比如:

<div id="a">    <div id="a-1" style="position:relative;">a-1</div></div><div id="b">b</div>

  b位于文档流a之后,所有b会覆盖a,而a-1又由于设定了position的值,所以a-1会覆盖b。

  在不使用position属性的节点上使用z-index属性,z-index不会改变叠放顺序。所以要利用z-index来改变叠放的顺序,节点上必须有position属性。

  z-index的值可以取负数,0,正数,auto。那么什么时候z-index的值为auto呢?对于使用了position属性但是没有用z-index的值的节点,在IE6/7中,z-index默认为0,而其他浏览器默认是auto。z-index为0和auto的区别是:z-index为0的节点要参与层级比较,而z-index为auto的节点不参与层级关系比较。

   所有节点都使用了position属性(relative/absolute/fixed),z-index为0的节点与z-index为auto的节点在同一层级内没有高低之分,而z-index大于等于1的节点高于z-index为0或者auto的节点,z-index为负数的节点低于z-index为0或者auto的节点。

<div id="a" style="position:absolute;z-index:2;">a</div><div id="b" style="position:absolute;z-index:0">b</div><div id="c" style="position:absolute;">c</div><div id="d" style="position:absolute;z-index:-1;">d</div>

  c没有设定z-index的值,所以z-index的值为auto,a的z-index的值为2大于b,c,d,所以在最上面,而b的z-index的值为0,虽然在同一层级内b,c没有高低之分,但是在文档流中c位于b之后,所以b在c的下面,d的z-index为-1,所以在最下面。

  一旦为一个节点指定了z-index(不为auto),该节点就会建立自己的局部叠放上下文。意味着,节点的所有后代相对于该节点(指定了z-index)都有其自己的叠放顺序。

   如果a,b节点定义了position:absolute,a节点的z-index比b节点大,那么a节点的所有子节点会覆盖b节点以及子节点。比如:

<div id="a" style="position:absolute;z-index:2">    <div id="a-1" style="position:absolute;z-index:1">a-1</div></div><div id="b" style="position:absolute;z-index:1">    <div id="b-1" style="position:absolute;z-index:3">b-1</div></div>

  由于a的z-index大于b的z-index的值,所以a会覆盖b,a的子节点a-1也会覆盖b,即使b的子节点b-1的z-index值为3比a-1大。

   为某个节点指定了z-index值,且该值不为auto,那么该节点会建立局部叠放上下文,后代节点会参照该节点。但是如果某个节点设定了position的值,但是未设定z-index属性时,即z-index在IE6/7中为0,其他浏览器中为auto。当z-index为auto时,该节点不会建立局部叠放上下文,那么该节点的后代节点该怎么办呢?由此引出定位树的概念。

   浏览器在渲染DOM节点时,除了生成DOM树之外,还会根据DOM树种的定位元素(position不为static)生成定位树。

   ⑥ 根据定位树来确定层级关系,z-index 为 auto 的节点不参与层级关系的比较, 由向上遍历至此且 z-index 不为 auto 的节点来参与比较。比如:

<div id="a" style="position:absolute;z-index:2"><div id="a-1" style="position:relative;z-index:100">        a-1    </div>        </div><div id="b"><div id="b-1"><div id="b-1-1" style="position:relative;z-index:10;">b-1-1</div>    </div>        </div><div id="c" style="position:absolute"><div id="c-1"><div id="c-1-1"><div id="c-1-1-1" style="position:absolute;z-index:5">c-1-1-1</div>        </div>    </div></div>

           

  在除IE6/7的浏览器中,c的z-index值为auto,所以它不参与层级比较,它也不为后代建立层叠上下文,后代元素逐级寻找z-index不为auto的最近的祖先元素。此次的层级关系为:

  • a>c>b       因为a的z-index为2,c的z-index为auto,文档流中c在b的后面,所以c>b
  • b-1-1>a     因为b-1-1逐级向上寻找z-index不为auto的祖先节点,最后它与a在同一个层叠上下文中,且b-1-1的z-index为10,所以b-1-1层级大于a
  • a<c-1-1-1<b-1-1   因为c-1-1-1逐级向上寻找z-index不为auto的祖先节点,最后它与a、b-1-1在同一个层叠上下文中,且c-1-1-1的z-index为5,所以它大于a,小于b-1-1

   在IE6/7的浏览器中,c的z-index值为0,当z-index为0,会参与层级关系比较,会建立自己的局部层叠上下文。此时的层级关系为:

  • a>c>b     a的z-index为2,c的z-index为0,所以a>c
  • b-1-1>a>c
  • c-1-1-1<b-1-1  因为c的z-index为0,c<b-1-1,c建立自己的局部层叠上下文,所以c-1-1-1<b-1-1

注意:1.IE6/7 下 position 不为 static, 且 没有z-index属性时 ,z-index 为 0, 除此之外的浏览器 z-index 为 auto。

   2.z-index为0会参与层级比较,建立局部层叠上下文,影响子节点的层级。z-index为auto不参与层级比较,不会建立局部层叠上下文,子节点逐级向上寻找最近的z-index不为auto的节点。

 

参考文章:http://www.neoease.com/css-z-index-property-and-layering-tree/comment-page-1/

         http://www.neoease.com/css-z-index-dom-tree-to-layering-tree/

 

CSS z-index属性