彻底理解z-index,看完还是只会无厘头的设置9999你打我~~~~

栏目: Html · 发布时间: 5年前

内容简介:今天写代码用antd-mobile的checkbox时候,想在内容文本后面添加一个icon,并且需要对这个icon绑定事件,发现绑定之后怎么也点不中,调试发现原来被层层嵌套的dom元素盖住了,肯定是z-index在作祟。可是按照我之前对z-index的了解(自信满满)却怎么也不能把他由“被盖住”改成“盖住别人”,在一通“盲改”代码之后,终于“盖住”其他dom元素了。然而心里总是在想难道之前自己对z-index的认知有问题么,抱着这样的心态决定重新去学习,下面进入正文其实我想说大部分前端开发是不重视css的,

今天写代码用antd-mobile的checkbox时候,想在内容文本后面添加一个icon,并且需要对这个icon绑定事件,发现绑定之后怎么也点不中,调试发现原来被层层嵌套的dom元素盖住了,肯定是z-index在作祟。可是按照我之前对z-index的了解(自信满满)却怎么也不能把他由“被盖住”改成“盖住别人”,在一通“盲改”代码之后,终于“盖住”其他dom元素了。然而心里总是在想难道之前自己对z-index的认知有问题么,抱着这样的心态决定重新去学习,下面进入正文

90%的前端开发对z-index的认知

其实我想说大部分前端开发是不重视css的,也就导致了对css的很多属性认知都是表面的,这其中z-index就是最典型的一个,下面列举的错误认知还请大家对号入座:

  • z-index值越大越“靠近我们” -- 最初级的认知
  • 要搭配position: absolute | relative | fixed 使用才有用呢 -- 稍微进阶一些的认知
  • 比较两个兄弟节点谁更“靠近我们”,要看他们的同级父元素的比较呢。-- 可能是大部分前端的终极认知了

例如下面的例子:要比较div1-1-1 和 div2-1 是要看div1 和 div2 的比较结果呢

<div class="div1">
    <div>
        <div class="div1-1-1" />
    </div>
</div>
<div class="div2">
    <div class="div2-1" />
</div>

如果以上三个大家都中枪了,没关系,看完这篇文章你就永远告别了,在遇到z-index的问题再也不会“盲改,乱试”了

三个概念 -- 层叠上下文、层叠水平、层叠顺序

  1. 层叠上下文(stacking context)
    看到上下文这个关键词,我想大家应该会有一点概念,没错就是context。和你们认识的那个BFC、IFC里面的上下文是一个意思,其实我想说css世界里面看到context或者XXX上下文其实都是同一个意思,完全可以理解为自成一派,在自己的小世界里面随便折腾,不受其他的context影响。当然,这个context是可以被其他context包含同时也可以包含其他context
  2. 层叠水平(stacking level)
    层叠水平决定了在同一个层叠上下文中元素在Z轴上的显示顺序。
    页面中的所有元素(普通元素和层叠上下文元素)都有层叠水平。然而对普通元素的层叠水平探讨只局限在层叠上下文元素中。
    注:大家千万不要把层叠水平和z-index混为一谈,尽管某些情况下z-index确实可以影响层叠水平,但是也只局限于具有层叠上下文的元素,而层叠水平是所有元素都存在的
  3. 层叠顺序(stacking order)

    层叠顺序表示发生层叠时有着特定的垂直显示顺序(规则)。

    即:网上这张很流行的规则

    彻底理解z-index,看完还是只会无厘头的设置9999你打我~~~~

    关于这张图有一些补充:

    位于最下面的background/border 特指层叠上下文元素的 边框和背景色。每一个层叠顺序规则 仅适用当前层叠上下文元素的 小世界

    inline水平盒子指的是包括inline/inline-block/inline-table元素的层叠顺序,他们都是 同级别的

    单纯从层叠水平上看,实际上z-index:0和auto是可以看成一样的,但是在层叠上下文领域有着根本性的差异

深入了解层叠上下文

  1. 特性

    层叠上下文的层叠水平要比普通元素高

    层叠上下文可以阻断元素的混合模式

    层叠上下文可以嵌套,内部层叠上下文及其所有子元素均受制于外部的层叠上下文

    每个层叠上下文和兄弟元素独立,也就是说,当进行层叠变化或者渲染的时候,只需要考虑后代元素

    每个层叠上下文是自成体系的,当元素发生层叠的时候,整个元素被认为是在父层叠上下文的层叠顺序中

  2. 如何创建

    根元素 (HTML)

    z-index 值不为 "auto"的 绝对/相对定位(在firefox/ie浏览器下position: fixed也是可以的)

    一个 z-index 值不为 "auto"的 flex 项目 (flex item),即:父元素 display: flex|inline-flex

    opacity 属性值小于 1 的元素(参考 the specification for opacity)

    transform 属性值不为 "none"的元素

    mix-blend-mode 属性值不为 "normal"的元素

    filter值不为“none”的元素

    perspective值不为“none”的元素

    isolation 属性被设置为 "isolate"的元素

    position: fixed

    在 will-change 中指定了任意 CSS 属性,即便你没有直接指定这些属性的值( 参考这篇文章

    -webkit-overflow-scrolling 属性被设置 "touch"的元素

  3. 层叠上下文与层叠顺序

    文章中多次提到普通元素具备层叠上下文后层叠水平就会变高,那么他究竟在层叠顺序那个规则图的哪个位置呢

    把目光向上锁定,第二条列举了12个可以创建层叠上下文的方法,我们把他分为两类:第二三条和其他。

    依赖z-index取值的:位置取决于z-index的值

    不依赖z-index取值的:在图中第二高的位置,即:z-index = auto 或者 0

    用一个例子来说明:

    <div class="container">
        <div class="div1">111</div>
        <div class="div2">222</div>
    </div>
    .container {
      width: 500px;
      height: 500px;
      background-color: #000;
      color: #fff;
      transform: scale(1); 
      /* 给container创建层叠上下文 */
    }
    .div1 {
      padding: 50px;
      background-color: aqua;
      z-index: 0;
      position: relative;
      /* 给div1创建层叠上下文,层叠水平依赖z-index的取值 */
    }
    .div2 {
      padding: 50px;
      background-color: red;
      opacity: 0.8;
      /* 给div2创建层叠上下文,层叠水平依赖z-index的取值 */
      /* margin-top: -40px; */
    }

    这个例子中一目了然,div1和div2的层叠水平一样,都是在规则那张图的第二高的位置,不过div2在div1的dom节点后面,所以div2要比div1的层叠水平高,我们把margin-top的注释去掉看下:

    彻底理解z-index,看完还是只会无厘头的设置9999你打我~~~~

    要想使得div1在上面只需要把div1的z-index改成大于0的值就好了。

    还是上面的htl结构,接下来我们再来看一个有意思的例子:

    .container {
      width: 500px;
      height: 500px;
      background-color: #000;
      color: #fff;
      transform: scale(1);
      /* 给container创建层叠上下文 */
    }
    .div1 {
      padding: 50px;
      background-color: aqua;
      opacity: 0.8;
      /* 给div1创建层叠上下文,层叠水平在z-index:0 */
    }
    .div2 {
      padding: 50px;
      background-color: red;
      position: relative;
      margin-top: -40px;
    }

    大家肯定会说,div1明显盖过div2啊,可是我们来看下实际情况:

    彻底理解z-index,看完还是只会无厘头的设置9999你打我~~~~

    实际情况下面的div2盖过了div1,原因是当html元素设置定位属性的时候(absolute/relative),其z-index属性自动生效变成

    z-index: auto,所以这时候div1和div2的层叠水平是一致的,而div2在div1的dom节点后面,所以盖过了div1( 注意这里div2并没有变成层叠上下文元素,这是有本质区别的

常见错误认知解析

现在我们在一起看下文章开头提到的几个常见的错误认知:

  • z-index值越大越“靠近我们” -- 并不一定,首先要成为层叠上下文。或者如果比较的元素的父元素也是层叠上下文,那就完全取决于父元素了
  • 要搭配position: absolute | relative | fixed 使用才有用呢 -- 对了一部分,还有其他的条件也可以使元素称为层叠上下文元素
  • 比较两个兄弟节点谁更“靠近我们”,要看他们的同级父元素的比较呢。-- 如果同级父元素不是层叠上下文元素就不需要看“父元素的眼色”了

文章到这里就结束了,希望看完这篇文章的同学可以彻底理解z-index。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

程序员的呐喊

程序员的呐喊

[美]Steve Yegge / 徐旭铭 / 人民邮电出版社 / 2014-5-1 / 45.00元

《程序员的呐喊》的作者是业界知名的程序员—来自google的steve yegge,他写过很多颇富争议的文章,其中有不少就收录在这本书中。本书是他的精彩文章的合集。 《程序员的呐喊》涉及编程语言文化、代码方法学、google公司文化等热点话题。 对工厂业界的各种现象、技术、趋势等,作者都在本书中表达了自己独特犀利的观点。比如java真的是一门优秀的面向对象语言吗?重构真的那么美好吗?强......一起来看看 《程序员的呐喊》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

html转js在线工具
html转js在线工具

html转js在线工具