• 【转】没人告诉你关于z-index的一些事


    原文:https://www.w3cplus.com/css/what-no-one-told-you-about-z-index.html

    _____________________________________

    堆叠顺序

    z-index看上去很简单,z-index值大的元素在z-index值小的元素前面,对吧?但其实这只是z-index的一部分用法。很多程序猿都觉得很简单,没有花太多时间去认真阅读规则。

    HTML中的每一元素都是在其他元素的前面或者后面。这是众所周知的堆叠顺序(Stacking Order),这条规则在w3c规范里面说的很清楚,但我前面提到过了,大部分程序猿并不真正理解。

    如果没有涉及z-indexposition属性的话,那规则很简单,堆叠顺序就是元素在HTML中出现的顺序。(当然如果你对行内元素使用负margin的话,可能情况会复杂一些。)

    加上position属性的话,就是所有定位了得元素在没有被定位的元素前面。(一个元素被定位的意思这里指的是它有一个position属性,但是不是static,而是relative,absolute等)

    再加上z-index属性,事情就变得有点诡异。首先z-index值越大,越靠前。但是z-index属性只作用在被定位了的元素上。所以如果你在一个没被定位的元素上使用z-index的话,是不会有效果的。还有就是z-index会创建一个堆叠的上下文(Stacking Contexts),我们可以理解为一个层。

    堆叠上下文

    同一个父元素下面的元素会受父元素的堆叠顺序影响,所以堆叠上下文是我们理解z-index和堆叠顺序的关键。(下面为了简化,我们称堆叠上下文为层。)

    每一个层都有唯一的根节点。当一个元素创建一个层,那么它的所有子元素都会受到父元素的堆叠顺序影响。意味着如果一个元素位于一个最低位置的层,那你z-index设置得再大,它也不会出现在其它层元素的上面。

    现在我们来说说什么情况下会产生新的层:

    • 当一个元素位于HTML文档的最外层(<html>元素)
    • 当一个元素被定位了并且拥有一个z-index值(不为auto)
    • 当一个元素被设置了opacitytransformsfilterscss-regionspaged media等属性。

    一二条规则,Web开发者都知道,虽然他们不一定知道怎么描述

    最后一条,是很多非w3c规范里面的文章很少提到的。通常来讲,如果一个CSS属性需要做一些特效的话,它都会创建一个新的层。

    影响堆叠顺序的因素有很多,我推荐你去看w3c规范,这篇文章我们主要探讨关于层的内容。

    同一层里面的堆叠顺序

    下面是同一层里面的堆叠顺序(从后到前):

    • 层的根元素
    • 被定位了得元素并且z-index值为负,相同z-index的情况下,按照HTML元素的书写顺序排列,下面相同。
    • 没有被定位的元素
    • 被定位的元素,并且z-index值为auto
    • 被定位了的元素并且z-index值为正。

    注意:z-index值为负的元素比较特殊,他们会先被绘制,意味着他们可以出现在其他元素的后面,甚至出现在它的父元素后面。但是必要条件是该元素必须与父元素处于同一层,并且父元素不是这个层的根元素。一个很好的例子

    理解了如何和什么时候会产生一个新的层,那么下次如果你遇到z-index值设了很大,但是不起作用的话就去看看它的祖先是否产生了一个新的层。

    著作权归作者所有。
    商业转载请联系作者获得授权,非商业转载请注明出处。
    原文: https://www.w3cplus.com/css/what-no-one-told-you-about-z-index.html © w3cplus.com

    ___________________________________________

    关于z-index的问题是很多程序员都不知道它是如何起作用的。说起来不难,但是大部分人并没有花时间去看规范,这往往会照成严重的后果。

    你不信?那就一起来看看下面的问题。

    问题

    在下面的HTML我们写了3<div>元素,然后每个<div>元素里面都有一个<span>元素,每个<span>元素都有个背景色,并且使用absolute定位,为了能更清楚地看到z-index的效果,我们写了一些其他的样式。第一个<span>元素的z-index值为1,其他两个没有设置。

    代码如下:

    <div>
      <span class="red">Red</span>
    </div>
    <div>
      <span class="green">Green</span>
    </div>
    <div>
      <span class="blue">Blue</span>
    </div>
    
    .red, .green, .blue {
      position: absolute;
    }
    .red {
      background: red;
      z-index: 1;
    }
    .green {
      background: green;
    }
    .blue {
      background: blue;
    }
    

    然后挑战来了: 尝试把红色的<span>元素放到其他两个元素后面,但是必须遵守下面的规则:

    • 不能修改HTML的内容
    • 不能增加或修改任何元素的z-index属性
    • 不能增加或修改任何元素的position属性

    想挑战一些的话,就点击上面Codepen的Edit按钮去尝试一下吧。如果你不能做到,那就接着看下去。

    解决方案

    解决方案很简单,你只需要给红色的<span>标签增加一个opacity小于1,像下面这样:

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

    如果你觉得不可思议了,不相信透明度会影响叠加顺序,那么恭喜你,即将学习新的技能,一开始看到我也不信。

    接下来让我们来摸索一番。

    堆叠顺序

    z-index看上去很简单,z-index值大的元素在z-index值小的元素前面,对吧?但其实这只是z-index的一部分用法。很多程序猿都觉得很简单,没有花太多时间去认真阅读规则。

    HTML中的每一元素都是在其他元素的前面或者后面。这是众所周知的堆叠顺序(Stacking Order),这条规则在w3c规范里面说的很清楚,但我前面提到过了,大部分程序猿并不真正理解。

    如果没有涉及z-indexposition属性的话,那规则很简单,堆叠顺序就是元素在HTML中出现的顺序。(当然如果你对行内元素使用负margin的话,可能情况会复杂一些。)

    加上position属性的话,就是所有定位了得元素在没有被定位的元素前面。(一个元素被定位的意思这里指的是它有一个position属性,但是不是static,而是relative,absolute等)

    再加上z-index属性,事情就变得有点诡异。首先z-index值越大,越靠前。但是z-index属性只作用在被定位了的元素上。所以如果你在一个没被定位的元素上使用z-index的话,是不会有效果的。还有就是z-index会创建一个堆叠的上下文(Stacking Contexts),我们可以理解为一个层。

    堆叠上下文

    同一个父元素下面的元素会受父元素的堆叠顺序影响,所以堆叠上下文是我们理解z-index和堆叠顺序的关键。(下面为了简化,我们称堆叠上下文为层。)

    每一个层都有唯一的根节点。当一个元素创建一个层,那么它的所有子元素都会受到父元素的堆叠顺序影响。意味着如果一个元素位于一个最低位置的层,那你z-index设置得再大,它也不会出现在其它层元素的上面。

    现在我们来说说什么情况下会产生新的层:

    • 当一个元素位于HTML文档的最外层(<html>元素)
    • 当一个元素被定位了并且拥有一个z-index值(不为auto)
    • 当一个元素被设置了opacitytransformsfilterscss-regionspaged media等属性。

    一二条规则,Web开发者都知道,虽然他们不一定知道怎么描述

    最后一条,是很多非w3c规范里面的文章很少提到的。通常来讲,如果一个CSS属性需要做一些特效的话,它都会创建一个新的层。

    影响堆叠顺序的因素有很多,我推荐你去看w3c规范,这篇文章我们主要探讨关于层的内容。

    同一层里面的堆叠顺序

    下面是同一层里面的堆叠顺序(从后到前):

    • 层的根元素
    • 被定位了得元素并且z-index值为负,相同z-index的情况下,按照HTML元素的书写顺序排列,下面相同。
    • 没有被定位的元素
    • 被定位的元素,并且z-index值为auto
    • 被定位了的元素并且z-index值为正。

    注意:z-index值为负的元素比较特殊,他们会先被绘制,意味着他们可以出现在其他元素的后面,甚至出现在它的父元素后面。但是必要条件是该元素必须与父元素处于同一层,并且父元素不是这个层的根元素。一个很好的例子

    理解了如何和什么时候会产生一个新的层,那么下次如果你遇到z-index值设了很大,但是不起作用的话就去看看它的祖先是否产生了一个新的层。

    总结

    说了这么多,我们来给之前的代码加上堆叠顺序。

    <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><!-- 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>6变成1.1,我用'.'来标记它是新生成的层里面的第一个元素。

    最后我们来总结一下为什么红色的<span>会去到下面: 一开始有两个层,一个由根节点产生,一个由设置了z-index:1并且position:absolute的红色<span>产生。当我们设置了opacity时,产生了第三个层,并且第三个层把红色<span>产生的层包裹了,意味着刚开始的z-index的作用域只在第三个层里面。而所有的<div>都没有定位或者z-index,所以他们的堆叠顺序按照HTML出现顺序排列,于是第三个层就去到下面。

    著作权归作者所有。
    商业转载请联系作者获得授权,非商业转载请注明出处。
    原文: https://www.w3cplus.com/css/what-no-one-told-you-about-z-index.html © w3cplus.com

  • 相关阅读:
    Tomcat支持多少并发
    Redis高可用架构—Keepalive+VIP
    MapReduce运行原理
    hihoCoder 1015 KMP算法(kmp)
    <html>
    UI--仿IOS控件之ActionSheet样式 and more..
    redis集群
    mongodb及mongoclient在win7下的编译和使用
    @property与@synthesize的差别
    传智播客c/c++公开课学习笔记--邮箱账户的破解与邮箱安全防控
  • 原文地址:https://www.cnblogs.com/oxspirt/p/13992135.html
Copyright © 2020-2023  润新知