z-index引发的思考

今天话题是由z-index的偶然失效,引发的一系列问题。

一、序

从定义上看z-index真的是个很简单的属性,就是描述元素的层叠顺序,但是有时间我们会发现z-index并不会起作用。这时候我们就需要好好的理解一下z-index背后的问题。

二、抛开position和z-index

我们多知道position的默认值为static,z-index的默认值为auto。当我们抛开position和z-index的设置,我们会发现层叠顺序就是html元素的顺序,但是不要忘记还有float和display。这里我通过一个例子:

    div.item1   inline-block
    div.item2   float
    div.item3   block
image

从上面的结构我们可以知道层叠顺序由大到小为inline-block(inline也是一样),flaot,block。这里只用了几个常用的作比较,其他的你们也可以尝试尝试。

三、设置position

当position进来搞事情的时候,这就稍微有点复杂了。首先你要记住的:

  • 当元素设置position为absolute,relative或者fixed,它们的层叠顺序大于position为static的。

但是这里又有很多细节问题,例如:当我们的dom结构多次嵌套时:

    div.item1   A
        div.child1  C
    div.item2   B
    .item1 {
        background: red;
        .child1 {
            position: absolute;
            top: 100px;
            left: 150px;
            background: blue;
        }
    }

    .item2 {
        background: rgb(200,10,200);
    }
image

由上面的结论,我们知道当元素设置position不为static时,它的层叠顺序比position为static的元素大(这里我暂且用大来表示离用户越近,词穷-_-)。但是我们知道position中的absolute的规则:

  • absolute 定位是相对于 static 定位以外的第一个父元素进行定位【这里原先我也理解错了,谢谢路过的大神^_^】

所以这里就让我们很郁闷了,是吧?当我们的dom结构很复杂的时候,你突然来个positioned(position不为static)元素,可能就出现了不可控的情况。而实际上我们理想的情况是什么?拿上面的例子说,既然C是A的子元素,那么C的层叠顺序就不应该大于比A层叠顺序大的同级元素(这的确是你想要的。)

对于这种情况,我们只采用position的话,只能把A的同级和上级元素设置为positioned。

四、该z-index出场了

首先我们多知道,z-index真的是一个很单纯的属性,单纯到赋值多没有什么花样。但是我们通常多会用错他。他正确的使用场景:

  • 使用z-index的元素必须是positioned。

那么我们再来看上面的需求,我们可以通过这样的设置实现:

    .item1 {
        position: relative;
        z-index: -1;
    }
image

这里有人会这样想:B的默认z-index为auto,而你设置了A的z-index的为-1,当然C不会再覆盖B咯。但是真的是这样吗?

这时,你可以设置一下C的z-index,可以设置一个很大很大的值。但是并不会起作用,所以这里我们要引入一个新的概念--层叠上下文(stacking context)

五、层叠上下文(stacking context)

对于层叠上下文的概念,我相信看了上面的例子,你应该知道上面意思,可能表达还有点词穷。大白话就是:子元素要看设置层叠上下文的父元素的脸色行事了。其实说到层叠上下文,这里我们要意识到一点,如果你的元素不是positioned,可能谈层叠上下文就有点不靠谱了。

为什么我会说这句话,现在我们知道z-index的设置依赖于positioned,而你如果不设置positioned,单纯的html先后顺序,并不会给我们带来太大的困扰。

产生层叠上下文的情况:(下列多是基于positioned)

  • 设置z-index不为auto;(所以0与auto是有区别的)
  • opacity不为1;
  • CSS3新出的属性对层叠上下文产生了影响,例如transform不为none。还有其他的不常用的,我就不罗列了。

六、总结

到这里我们可以总结一下考虑层叠顺序的因素:

  • html元素的排列顺序
  • display与float
  • position
  • z-index的使用
  • 层叠上下文的产生

到这里如果你还是很疑惑的话,我表示很抱歉。这里送上两篇参考的文章:

FLYLEE