关于z-index那些事

关于z-index的真正问题是,不多有人理解它究竟是怎么用。其实它并不复杂,可是若是你历来没有花必定时间去看具体的z-index相关文档,那么你极可能会忽略一些重要的信息。html

例子

在接下来的HTML里 有三个<div>元素,而且每一个<div>里包含一个<span>元素。每一个<span>被分别给定一个背景颜色:红、绿、蓝。每一个<span>被放置到文档的左上角附近,部分重叠着其余 的<span>元素,这样你就能够看到哪些是被堆叠在前面。第一个<span>有一个z-index的值为1,而其余两个没有任 何z-index值。spa

代码:code

span{ 
            position: absolute; 
            display: block; 
            height: 100px; 
            width: 100px; 
        } 
        .red{ 
            background-color: red; 
            z-index: 1 
        } 
        .green{ 
            top: 40px; 
            left: 40px; 
            background-color: green; 
        } 
        .blue{ 
            top: 80px; 
            left: 80px; 
            background-color: blue; 
        }

    <div> 
        <span class="red"></span> 
    </div> 
    <div> 
        <span class="green"></span> 
    </div> 
    <div> 
        <span class="blue"></span> 
    </div>

 

image

 

那问题来了,如何将红色span元素堆在蓝色和绿色后面,不要打破如下规则:

  • 不要以任何方式改变HTML标记。htm

  • 不要添加/修改任何元素的z-index属性。blog

  • 不要添加/修改任何元素的position属性。排序

若是你找到了答案,那么它应该像下面这样ci

div:first-child{ 
            opacity:.99; 
        } 
        span{ 
            position: absolute; 
            display: block; 
            height: 100px; 
            width: 100px; 
        } 
        .red{ 
            background-color: red; 
            z-index: 1 
        } 
        .green{ 
            top: 40px; 
            left: 40px; 
            background-color: green; 
        } 
        .blue{ 
            top: 80px; 
            left: 80px; 
            background-color: blue; 
        }

<div> 
    <span class="red"></span> 
</div> 
<div> 
    <span class="green"></span> 
</div> 
<div> 
    <span class="blue"></span> 
</div> 

 

image

 

解决方案

这个解决方法是在第一个<div>里(红色<span>的父节点)添加一个小于1的opacity属性值。下面就是被添加的CSS的例子:开发

div:first-child{
opacity:.99;
}文档

很神奇吧,但仍然百思不得其解,而且不相信opacity能决定哪一个元素堆在前面。如今就了解一下z-index。get

堆栈顺序

z-index看上去如此简单:高的z-index堆在低的z-index的前面,对吗?这其实是错的,是z-index问题的一部分。它看上去如此的简单,以致于不少开发者没有花相应的时间去读相关的规则。

每个在HTML文档中的元素既能够在其余元素的前面,也能够在其余元素的后面。这就是所谓的堆栈顺序。决定这个顺序的规则被十分清楚的定义在说明文档中,可是就像以前我已经提到过,这些文档没有被大多数开发者们彻底弄明白。

当z-index和position属性不被包括在内时,这些规则至关简单:基本上,堆栈顺序和元素在HTML中出现的顺序同样。(好吧,实际上是有一点复杂的,可是只要你不使用压缩边界来重叠行内元素,你可能不会遇到边界问题。)

当你把位置属性也包括在内介绍时,任何定位元素(和他们的子元素)都在非定位元素前被显示出来。(说一个元素被“定位”意思是它有一个不一样于静态的位置值,例如相对的,绝对的,等等。)

最后,当z-index被说起时,事情变的有点儿复杂。最初,很天然的假设带有高z-index值的元素会在带有低z-index值的元素前面,可是后来发现没那么简单。首先,z-index只对定位元素起做用。若是你尝试对非定位元素设定一个z-index值,那么确定不起做用。其次,z-index值能建立堆栈上下文环境,而且忽然发现看似简单的东西变的更加复杂了。

堆栈上下文

一组具备共同双亲的元素,按照堆栈顺序一块儿向前或向后移动构成了所谓的堆栈上下文。充分理解堆栈上下文是真正掌握z-index和堆栈顺序工做原理的关键。

每个堆栈上下文都有一个HTML元素做为它的根元素。当一个新的堆栈上下文在一个元素上造成,那么这个堆栈上下文会限制全部的子元素以堆栈的顺序存储在一个特别的地方。那意味着一旦一个元素被包含在处于底部堆栈顺序的堆栈上下文中,那么就没有办法先出现于其余处于更高的堆栈顺序的不一样堆栈上下文元素,就算z-index值是十亿也不行

如今,堆栈上下文有三种方法能够在一个元素上造成:

  1. 当一个元素是文档的根元素时(<html>元素)。
  2. 当一个元素有一个position值而不是static,有一个z-index值而不是auto.
  3. 当一个元素有一个opacity值小于1

前两种造成堆栈上下文的方法具备很大意义而且被广大Web开发者所理解(即便他们不知道这些被叫作什么)。第三种方法(opacity)几乎历来没在w3c说明文档以外被说起过。

用堆栈顺序决定一个元素的位置

实际上,为一个页面上的全部元素决定全局堆栈顺序(包括边界、背景、文本节点、等等)是极度复杂的,而且远远超越了本文讲述的范围。可是咱们最大的目的,就是基本了解这个顺序,它可以在很长一段时间内帮助咱们提升CSS开发的可预测性。因此,让咱们打破顺序,分解为独立的堆栈上下文。

在一样堆栈上下文里的堆栈顺序

下面是几条基本的规则,来决定在一个单独的堆栈上下文里的堆栈顺序(从后向前):

  1. 堆栈上下文的根元素
  2. 定位元素(和他们的子元素)带着负数的z-index值(高的值被堆叠在低值的前面;相同值的元素按照在HTML中出现的顺序堆叠)。
  3. 非定位元素(按照在HTML中出现的顺序排序)
  4. 定位元素(和他们的子元素)带着auto的z-index值(按照在HTML中出现的顺序排序)
  5. 定位元素(和他们的子元素)带着正z-index值(高的值被堆叠在低值的前面;相同值的元素按照在HTML中出现的顺序堆叠)

注 解:定位元素带有负的z-index值被在一个堆栈上下文中先排序,这意味着他们出如今全部其余元素的后面。正因如此,它使一个元素出如今本身父元素以后 成为可能,这之前一般是不可能的事。固然,这局限于它的父元素与它在同一个堆栈上下文,而且不是那个堆栈上下文的根元素。

全局堆栈顺序

坚决的理解了为何/何时新的堆栈上下文造成,同时掌握了同一个堆栈上下文的堆栈顺序,如今让你来找出一个特定元素将出如今全局堆栈里的顺序不是那么糟糕了吧?

避免错误的关键是可以发现新的堆栈上下文何时造成。若是你对一个元素设置了z-index值为十亿可是它没有在堆栈顺序中向前移动,检查一下它的祖先树,看是否它的父节点造成了堆栈上下文。若是是那样的话,你的z-index值即便有十亿也不会给你带来好处。

回到例子

回到以前的原始问题,我已经重建了这个HTML的结构,添加了一些注释,每个标签指明了它在堆栈里的顺序。这个顺序是假设最初的CSS。

<div><!-- 1 -->
        <span class="red"><!-- 6 --></span>
    </div>
    <div><!-- 2 -->
        <span class="green"><!-- 4 --></span>
    </div>
    <div><!-- 3 -->
        <span class="blue"><!-- 5 --></span>
    </div>

当咱们添加opacity到第一个<div>,堆栈顺序像下面这样改变:

<div><!-- 1 -->
        <span class="red"><!-- 1.1 --></span>
    </div>
    <div><!-- 2 -->
        <span class="green"><!-- 4 --></span>
    </div>
    <div><!-- 3 -->
        <span class="blue"><!-- 5 --></span>
    </div>

span.red曾经的顺序是6,但如今改成1.1。我已经使用“.”来标注一个新的上下文环境的造成。span.red如今是那个新的上下文的第一个元素。

如今彷佛更清晰了,关于为何红色盒子跑到其余盒子的后面。原始的例子只包含两个堆栈上下文,根元素和造成span.red的那个。当咱们添加 opacity到span.red的父节点上,造成了第三个堆栈上下文,结果显示在span.red上的z-index值只能应用在那个新的堆栈上下文 中。由于第一个<div>(应用opacity的那个)和它的兄弟元素没有position或者z-index值的集合,他们的堆栈顺序是由 他们在HTML里的源顺序决定的,也就是说第一个<div>,和它的堆栈上下文里的全部元素被第二个和第三个<div>元素分离。

总结

简单来讲,opacity会创造新的堆栈上下文,z-index比较通常是在同一堆栈内比较才有效果 。mozzila官方https://developer.mozilla.org/en-US/docs/CSS/Understanding_z-index/The_stacking_context?redirectlocale=en-US&redirectslug=Understanding_CSS_z-index%2FThe_stacking_context

相关文章
相关标签/搜索