CSS中z-index全解析

一、z-index解释

z-index属性决定了一个HTML元素的层叠级别,元素层叠级别是相对于元素在Z轴上(与X轴Y轴相对照)的位置而言。一个更高的z-index值意味着这个元素在叠层顺序中会更靠近顶部。这个层叠顺序沿着垂直的线轴被呈现。

在一个HTML页面中,自然的层叠顺序(也就是元素在Z轴上的顺序)是由很多因素决定的:

  • 具有负值的stacking contexts(层叠环境)元素,按照出现的先后顺序排列(越靠后层级越靠上);
  • 没有被定位,没有浮动的块级元素,按照出现的先后顺序排列;
  • 没有被定位,有浮动的元素,按照出现的先后顺序排列;
  • 内联元素,按照出现的先后顺序排列排列;
  • 被定位的元素,按照出现的先后顺序排列;
  • Z-index 属性,当被正确使用的时候,会改变自然的层叠顺序。

二、顺序规则

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

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>z-index练习</title>
    <style>
        div{width: 200px; height: 200px;}
        .a{ background-color: red;}
        .b{ background-color: green; margin-top: -100px; margin-left: 100px;}
    </style>
</head>
<body>
    <div class="a">A</div>
    <div class="b">B</div>
</body>
</html>

 

二、定位规则

2.1 如果将 position 设为 static, 位于文档流后面的节点依然会遮盖前面的节点浮动, 所以 position:static 不会影响节点的遮盖关系.

    <style> 
        div{width: 200px; height: 200px;}
         .a{ background-color: red; position: static;}
         .b{ background-color: green; margin-top: -100px; margin-left: 100px;}
    </style>

2.2 如果将 position 设为 relative (相对定位), absolute (绝对定位) 或者 fixed (固定定位), 这样的节点会覆盖没有设置 position 属性或者属性值为 static 的节点, 说明前者比后者的默认层级高.

    <style>
        div{width: 200px; height: 200px;}
        .a{ background-color: red; position: relative;}
        .b{ background-color: green; margin-top: -100px; margin-left: 100px;}
    </style>

 

2.3 在没有 z-index 属性干扰的情况下, 根据顺序规则和定位规则, 我们可以做出更加复杂的结构. 这里我们对 A 和 B 都不设定 position, 但对 A 的子节点 A-1 设定 position:relative. 根据顺序规则, B 会覆盖 A, 又根据定位规则 A-1 会覆盖 B.

...
<
style> div{width: 200px; height: 200px;} .a{ background-color: red;} .a-1{width: 130px; height: 130px; background-color: blue; position: relative;} .b{ background-color: green; margin-top: -100px; margin-left: 100px;} </style> </head> <body> <div class="a">这里是A的内容 <div class="a-1">A-1</div> </div> <div class="b">这里是B的内容</div> </body>
...

三、参与规则

不用 position 属性, 在节点加上 z-index 属性. z-index 对节点是不起作用的.

W3C 对 z-index 属性的描述中提到 在 z-index 属性仅在节点的 position 属性为 relative, absolute 或者 fixed 时生效.

此处不做演示

四、默认值规则

如果所有节点都定义了 position:relative. z-index 为 0 的节点与没有定义 z-index 在同一层级内没有高低之分;

但 z-index 大于等于 1 的节点会遮盖没有定义 z-index 的节点; z-index的值为负数的节点将被没有定义 z-index 的节点覆盖.

...
<
style> div{width: 200px; height: 200px; position: relative;} .a{ background-color: red;} .b{ background-color: green; margin-top: -100px; margin-left: 100px; z-index: 1} .c{ background-color: yellow; margin-top: -100px; margin-left: 200px;} .d{ height: 450px; width: 450px; background-color: blue; color: #fff; margin-top: -400px; margin-left:0px; z-index: -1;} </style> </head> <body> <div class="a">这里是A的内容</div> <div class="b">这里是B的内容</div> <div class="c">这里是C的内容这里是C的内容</div> <div class="d">这里是D的内容这里是D的内容这里是D的内容</div> </body>
...

当 position设为 relative, absolute 或者 fixed, 而没有设置 z-index 时, IE8 以上和 W3C 浏览器 (下文我们统称为 W3C 浏览器) 的 z-index 默认值是 auto, 但 IE6 和 IE7 是 0.

五、从父规则

5.1 如果 A, B 节点都定义了 position:relative, A 节点的 z-index 比 B 节点大, 那么 A 的子节点必定覆盖在 B 的子节点前面. 

...
<
style> div{width: 200px; height: 200px;} .a{ background-color: red; position: relative; z-index: 2;} .b{ background-color: green; margin-top: -100px; margin-left: 100px; position: relative; z-index: 1} .a-1,.b-1{ background-color: yellow; width: 160px; height: 120px;} </style> </head> <body> <div class="a">这里是A的内容 <div class="a-1">这里是A的子内容A-1</div> </div> <div class="b">这里是B的内容这里是B的内容 <div class="b-1">这里是B的子内容B-1</div> </div> </body>
...

5.2 如果所有节点都定义了 position:relative, A 节点的 z-index 和 B 节点一样大, 但因为顺序规则, B 节点覆盖在 A 节点前面. 就算 A 的子节点 z-index 值比 B 的子节点大, B 的子节点还是会覆盖在 A 的子节点前面. 

...
<
style> div{width: 200px; height: 200px;} .a{ background-color: red; position: relative; z-index: 1;} .b{ background-color: green; margin-top: -100px; margin-left: 100px; position: relative; z-index: 1} .a-1,.b-1{ width: 160px; height: 120px; position: relative;} .a-1{ background-color: yellow; z-index: 999;} .b-1{ background-color: blue;} </style> </head> <body> <div class="a">这里是A的内容 <div class="a-1">这里是A的子内容A-1</div> </div> <div class="b">这里是B的内容这里是B的内容 <div class="b-1">这里是B的子内容B-1</div> </div> </body>
...

很多人将 z-index 设得很大, 9999 什么的都出来了, 如果不考虑父节点的影响, 设得再大也没用, 那是无法逾越的层级.  

六、层级树规则

可能你会觉得,在 DOM 结构中的兄弟节点会拎出来进行比较并确定层级, 其实不然.

...
<style>
    div{width: 200px; height: 200px;}
    .a{ background-color: red; position: relative; z-index: 2;}
    .b{ background-color: green; margin-top: -100px; margin-left: 100px;}
    .a-1,.b-1{ width: 160px; height: 120px;}
    .a-1{ background-color: yellow; position: relative; z-index: 0;}
    .b-1{ background-color: blue; position: relative; z-index: 1; }
</style>
</head>
<body>
    <div class="a">这里是A的内容
        <div class="a-1">这里是A的子内容A-1</div>
    </div>
    <div class="b">这里是B的内容这里是B的内容
        <div class="b-1">这里是B的子内容B-1</div>
    </div>
</body>
...

我们认为同时将 position 设为 relative, absolute 或者 fixed, 并且 z-index 经过整数赋值的节点, 会被放置到一个与 DOM 不一样的层级树里面, 并且在层级树中通过对比 z-index 决定显示的层级. 上面的例子如果用层级树来表示的话, 应该如下图所示.

图中虽然 A-1 (z-index:0) 的值比 B-1 (z-index:1) 小, 但因为在层级树里 A (z-index:2) 和 B-1 在一个层级, 而 A 的值比 B-1 大, 根据从父规则, A-1 显示在 B-1 前面. 

七、参与规则 2

前面提到的参与规则认为只要节点的 position 属性为 relative, absolute 或者 fixed, 即可参与层级比较, 其实不准确. 如果所有节点都定义了 position:relative, 并且将 z-index 设为整数值, 根据从父规则, 父节点的层级决定了子节点所在层级.

例子中 A, B-1, C 作为父节点, z-index 的值相同, 根据顺序规则, C 在 B-1 之前, B-1 在 A 之前; 又根据从父规则, 无论子节点的 z-index 值是什么, C-1-1-1 在 B-1-1 之前, B-1-1 在 A-1 之前.

如果我们将所有父节点的 z-index 属性去除, 诡异的事情发生了. IE6 和 IE7 浏览器显示效果不变, 而 W3C 浏览器的子节点不再从父, 而是根据自身的 z-index 确定层级.

根据默认值规则, IE6 / IE7 和 W3C 浏览器上的元素存在 z-index 默认值的区别. 我们相信, 仅当 position 设为 relative, absolute 或者 fixed, 并且 z-index 赋整数值时, 节点被放置到层级树; 而 z-index 为默认值时, 只在 document 兄弟节点间比较层级. 在 W3C 浏览器中, A, B-1 和 C-1-1 的 z-index 均为 auto, 不参与层级比较.

而在 IE6 和 IE7 中, 因为 z-index 的默认值是 0, 所以也参与了层级比较.

设置了 position 而没有 z-index 的节点虽然不参与层级树的比较, 但还会在 DOM 中与兄弟节点进行层级比较.

我们对上个例子改造一下, 将 B-1 的 position 属性删除后, W3C 浏览器显示如下图. 根据定位规则, A 和 C 会显示在 B-1 的前面; 而根据顺序规则, C 又显示在 A 前面. 

在 IE6 和 IE7 中, 因为 A 和 C-1-1 设置了 position:relative, 而且 z-index 的默认值为 0, 所以也参与层级树比较, 所以有如下效果.

转自:http://www.xiaoxiangzi.com/Programme/CSS/7884.html

posted @ 2016-04-14 17:08  奔跑的蜗牛~  阅读(1097)  评论(0编辑  收藏  举报