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

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

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

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

  • 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的问题不再会“盲改,乱试”了web

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

  1. 层叠上下文(stacking context)
    看到上下文这个关键词,我想你们应该会有一点概念,没错就是context。和大家认识的那个BFC、IFC里面的上下文是一个意思,其实我想说css世界里面看到context或者XXX上下文其实都是同一个意思,彻底能够理解为自成一派,在本身的小世界里面随便折腾,不受其余的context影响。固然,这个context是能够被其余context包含同时也能够包含其余context
  2. 层叠水平(stacking level)
    层叠水平决定了在同一个层叠上下文中元素在Z轴上的显示顺序。
    页面中的全部元素(普通元素和层叠上下文元素)都有层叠水平。然而对普通元素的层叠水平探讨只局限在层叠上下文元素中。
    注:你们千万不要把层叠水平和z-index混为一谈,尽管某些状况下z-index确实能够影响层叠水平,可是也只局限于具备层叠上下文的元素,而层叠水平是全部元素都存在的
  3. 层叠顺序(stacking order)
    层叠顺序表示发生层叠时有着特定的垂直显示顺序(规则)。
    即:网上这张很流行的规则
    clipboard.png浏览器

    关于这张图有一些补充:
    位于最下面的background/border特指层叠上下文元素的边框和背景色。每个层叠顺序规则仅适用当前层叠上下文元素的小世界
    inline水平盒子指的是包括inline/inline-block/inline-table元素的层叠顺序,他们都是同级别的
    单纯从层叠水平上看,实际上z-index:0和auto是能够当作同样的,可是在层叠上下文领域有着根本性的差别antd

深刻了解层叠上下文

  1. 特性

    层叠上下文的层叠水平要比普通元素高
    层叠上下文能够阻断元素的混合模式
    层叠上下文能够嵌套,内部层叠上下文及其全部子元素均受制于外部的层叠上下文
    每一个层叠上下文和兄弟元素独立,也就是说,当进行层叠变化或者渲染的时候,只须要考虑后代元素
    每一个层叠上下文是自成体系的,当元素发生层叠的时候,整个元素被认为是在父层叠上下文的层叠顺序中dom

  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. 层叠上下文与层叠顺序flex

    文章中屡次提到普通元素具有层叠上下文后层叠水平就会变高,那么他究竟在层叠顺序那个规则图的哪一个位置呢
    把目光向上锁定,第二条列举了12个能够建立层叠上下文的方法,咱们把他分为两类:第二三条和其余。
    依赖z-index取值的:位置取决于z-index的值
    不依赖z-index取值的:在图中第二高的位置,即:z-index = auto 或者 0spa

    用一个例子来讲明:

    <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的注释去掉看下:

    clipboard.png
    要想使得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啊,但是咱们来看下实际状况:

    clipboard.png

    实际状况下面的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。

相关文章
相关标签/搜索