zoukankan      html  css  js  c++  java
  • z-index和层叠上下文

    z-index基础介绍:
    三维坐标空间里,x轴通常用来表示水平位置,y轴来表示垂直位置,还有z轴来表示在纸面内外方向上的位置,像下面的图片一样:

    clipboard.png

    css允许的z-index的值是
    ● auto (自动,默认值)
    ● (整数)
    ● inherit (继承)
    当设置成整数时,值越大越靠近用户。
    如果有两个元素放在了一起,占据了一块共同的区域,那么有着较大z-index值的元素就会掩盖有着较低z-index值的元素在共同区域的那一部分。

    关于z-index的三个思考
    ● 当一个设置了z-index值的定位元素与正常的文档流中的元素相互重叠的时候,谁会被置于上方?
    ● 当定位元素与浮动元素相互重叠的时候,谁会被置于上方?
    ● z-index必须要与定位一起使用才会生效吗?
    ● z-index大的元素一定会遮挡z-index小的元素吗?
    解决上面的问题需要深入理解z-index的原理,需要知道层叠上下文和层叠顺序。

    层叠上下文的概念:
    层叠上下文就是html中的一个三维概念。相当于在水平面创建了一个z轴,有了层叠上下文的元素会离用户更近。它包含了一组层叠层的元素。我们所创建的每一个网页都有一个默认的层叠上下文,层叠上下文的根就是html,其他的所有元素都会在这个层叠上下文占据一个层叠水平,或高或低。

    层叠顺序:
    层叠顺序:这是一种规则,表示元素发生重叠时,在z轴上的显示顺序。
    在一个层叠上下文中,有七种层叠顺序:

    clipboard.png

    (1) 背景和边框:建立层叠上下文的元素的背景和边框,层叠中的最低级别
    (2) 负的z-index:z-index 为负值时形成的层叠上下文
    (3) 块级盒子: 文档流中正常的块级元素
    (4) 浮动盒子:非定位的浮动盒子
    (5) 行内盒:文档流内的行内级盒子
    (6) z-index:0 定位元素,这些元素建立了新的层叠上下文。
    (7) 正的z-index:层叠中的最高级别。

    页面中内联元素的层叠顺序要比浮动元素和块状元素都高的原因,浮动和块级盒子主要用来布局,而内联的元素用来显示页面内容。所以比起他的要高。

    ps: 图上缺少的信息
    inline和inline-block是一个同一个level
    z-index:0实际上和z-index:auto单纯从层叠水平上看,是可以看成是一样的。

    层叠顺序规则
    谁大谁上:当具有明显的层叠水平标示的时候,比如说z-index值,在同一个层叠上下文领域,层叠水平值大的那一个覆盖小的那一个
    后来居上:当元素的层叠水平一致、层叠顺序相同的时候,在DOM流中处于后面的元素会覆盖前面的元素。

    层叠上下文元素的特性
    ● 层叠上下文的层叠水平要比普通元素高;
    ● 层叠上下文可以嵌套,内部层叠上下文及其所有子元素均受制于外部的层叠上下文。
    ● 每个层叠上下文不会影响它的兄弟元素,当进行层叠变化或渲染的时,只和该元素的后代元素有关。
    ● 每个层叠上下文是独立的,当元素发生层叠的时,它的层叠顺序依赖在父层叠上下文的层叠顺序中。

    层叠上下文的创建
    (1)根层叠上下文:
    指的是页面根元素,也就是html元素。这就是为什么,绝对定位元素在left/top等值定位的时候,如果没有其他定位元素影响,会相对浏览器窗口定位的原因。
    (2)定位元素
    含有position的值是relative或absolute的定位元素,以及FireFox/IE浏览器(Chrome等webkit内核浏览器是fixed的自动形成层叠上下文,无需将z-index设置成数值)下含有position:fixed的定位元素,当其z-index值不是auto的时候,会创建层叠上下文。
    demo:
    (1)

    <div style="position:relative; z-index:auto;">
        <img src="./cat.jpg" style="position:absolute; z-index:2;" class="cat"> 
    </div>
    
    <div style="position:relative; z-index:auto;">
       <img src="./dog.jpg" style="position:relative; z-index:1;" class="dog"> 
    </div>

    结果:

    clipboard.png

    (2)

    <div style="position:relative; z-index:0;">
        <img src="./cat.jpg" style="position:absolute; z-index:2;" class="cat"> 
    </div>
    <div style="position:relative; z-index:0;">
        <img src="./dog.jpg" style="position:relative; z-index:1;" class="dog"> 
    </div>

    结果:

    clipboard.png

    原因:
    z-index 值是auto,是一个普通元素,两个img层比较不受父级的影响,按照规则谁大谁上,于是,z-index为2的猫覆盖值为1的狗
    z-index:0会创建一个层叠上下文。此时,层叠规则就发生了变化。层叠上下文特性里最后一条规则,每个层叠上下文都是独立的。两个img的层叠顺序比较变成了优先比较其父级层叠上下文元素的层叠顺序。由于两者都是z-index:0,一样大,此时,遵循层叠规则后来居上,根据在DOM出现的先后顺序决定谁在上面,于是,位于后面的狗覆盖猫。此时img元素上的z-index是没有任何意义的。

    E6/IE7浏览器有个bug,就是z-index:auto的定位元素也会创建层叠上下文。

    (3) CSS3下的层叠上下文
    CSS3的一些新属性,会创建局部的层叠上下文,并且transform属性会改变绝对定位的字元素的包含块。
    以下几种情况会产生新的层叠上下文:
    1.z-index值不为auto的flex项(父元素display:flex|inline-flex).
    2.元素的opacity值不是1.
    3.元素的transform值不是none.
    4.元素mix-blend-mode值不是normal.
    5.元素的filter值不是none.
    6.元素的isolation值是isolate.
    7.will-change指定的属性值为上面任意一个。
    8.元素的-webkit-overflow-scrolling设为touch.

    display:flex|inline-flex与层叠上下文
    需要满足两个条件才能形成层叠上下文:
    (1) 父级需要是display:flex/inline-flex
    (2) 子元素的z-index不是auto,必须是数值。
    此时,这个子元素为层叠上下文元素,没错,注意了,是子元素,不是flex父级元素
    demo:

     <div class="box">
        <div>
            <img src="./dog.jpg" class="dog">
        </div>
    </div>
    
    .box div {
         300px;
        height: 300px;
        background-color: pink;
        z-index: 101;
    }
    .box div img {
         400px;
        height: 200px;
        position: relative;
        z-index: -1;
    }

    结果:

    clipboard.png

    原因:此时的div是一个普通的元素,它上面设置的z-index是无效的,img的负值z-index会被块级元素所遮挡。

    接上:

    .box {
        display: flex;
    }

    结果:

    clipboard.png

    div加上flex值之后,此时的z-index就会生效,会使它的子元素既内部的div形成层叠上下文。根据7层的层叠顺序,background的那层会被负的z-index的那层所遮挡。
    flex的出现打破了传统的z-index必须与定位的元素一起使用才会生效的观念。

    opacity与层叠上下文

    <div>
        <img src="./dog.jpg" class="dog">
    </div>
    
    div {
         300px;
        height: 300px;
        background-color: pink;
    }
    div img {
         400px;
        height: 200px;
        position: relative;
        z-index: -1;
    }

    结果:

    clipboard.png

    给div加一个opacity的属性:

    div {
         300px;
        height: 300px;
        background-color: pink;
        opacity: 0.5; /* 添加opcity属性 */
    }

    只要设置的opacity的值不是1,就会形成层叠上下文。
    表现结果:

    clipboard.png

    transform对层叠上下文的影响
    同上,对外层的div设置transform: rotate(15deg),会形成层叠上下文,导致图片显示在div的上面。

    transform除了建立局部的层叠上下文还会改变绝对定位(固定定位也是绝对定位的一种)子元素的包含块,
    包含块的概念:一些盒子根据它外面的矩形盒子计算得到自身的定位和大小,这个外层的矩形盒子就是包含块。

    对固定定位的元素的影响
    正常的固定定位的包含块是视口,加了transform就不一样了

    <div id="transform">
        <div id="fixed"></div>
    </div>
        
    div {
         100px;
        height: 100px;
    }
    #fixed {
        position: fixed;
         100%;
        height: 100%;
        top: 0;
        left: 0;
        background: blue;
    }
    #transform {
        background: red;
        padding: 20px;
    }

    fixed将会铺满整个屏幕。
    结果:
    clipboard.png

    上面加上

    #transform {
        transform: scale(1);
    }

    结果:

    clipboard.png

    原因,fixed的包含块不再是视口,而是transform这个div最边缘。所以fixed的宽高均为140px

    对绝对定位的元素的影响:

    <div id="relative">
        <div id="transform">
            <div id="absolute"></div>
        </div>
    </div>
    
    #relative {
        position: relative;
         100px;
        height: 100px;
        background: green;
    }
    #absolute {
        position: absolute;
         100%;
        height: 100%;
        top: 0;
        left: 0;
        background: blue;
    }
    #transform {
        background: red;
         50px;
        height: 50px;
    }

    此时absolute的包含块为relative的内边距盒的边缘盒。所以absolute的宽高是100px
    给transform div加上transform属性

    结果:

    clipboard.png

    由于transform创建了局部层叠上下文,absolute的包含块不再是 relative而是transform了,根据这一新的包含块,得新宽和高为50px。
    只要是有了transform这个属性不论它的值是什么都会影响绝对定位的子包含块。

    总结 :
    层叠上下文的元素的层叠顺序在哪一层:
    依赖z-index值的元素,根据z-index的值来决定。
    不依赖z-index的值的元素,它们的z-index的auto值相当于z-index:0级别。

    第二种情况解释了为什么定位的元素会覆盖掉普通流中的元素。定位的元素,会默认加上z-index: auto,按照7种层叠顺序,会遮盖普通流的元素。

    当z-index的值同是auto,就是说层叠上下文的元素和定位的元素处于同一个层叠顺序时,当她们发生重叠时,后面的元素会遮盖上面的元素:

    <img src="./dog.jpg" style="opacity: 0.5" class="dog"> 
    <img src="./cat.jpg" style="position:relative; margin-left:-100px;" class="cat"> 

    clipboard.png

    上面的元素调换位置:

    <img src="./cat.jpg" style="position:relative; margin-left:-100px;" class="cat"> 
    <img src="./dog.jpg" style="opacity: 0.5" class="dog"> 
    

    clipboard.png

    z-index本质上还是谁大谁在上面,虽然css3新加的一些属性使z-index变的复杂,最常见的影响可能就是flex布局导致的,但是规则还是按照7种层叠顺序来排布。

  • 相关阅读:
    ubuntu下安装maven
    159.Longest Substring with At Most Two Distinct Characters
    156.Binary Tree Upside Down
    155.Min Stack
    154.Find Minimum in Rotated Sorted Array II
    153.Find Minimum in Rotated Sorted Array
    152.Maximum Product Subarray
    151.Reverse Words in a String
    150.Evaluate Reverse Polish Notation
    149.Max Points on a Line
  • 原文地址:https://www.cnblogs.com/10manongit/p/12804839.html
Copyright © 2011-2022 走看看