zoukankan      html  css  js  c++  java
  • 深入理解CSS定位中的堆叠z-index

    前面的话

      对于所有定位,最后都不免遇到两个元素试图放在同一位置上的情况。显然,其中一个必须盖住另一个。但,如何控制哪个元素放在上层,这就引入了属性z-index

    定义

      利用z-index,可以改变元素相互覆盖的顺序。这个属性的名字由坐标系统得来,其中从左向右是x轴,从上到下是y轴。从屏幕到用户是z轴。在这个坐标系中,较高z-index值的元素比较低z-index值的元素离用户更近,这会导致较高z-index值的元素覆盖其他元素,这也称为堆叠或叠放

    z-index

      值: <integer> | auto | inherit

      初始值: auto

      应用于: 定位元素

      继承性: 无

      [注意]z-index应用于定位元素是CSS2的规范,到了CSS3标准,z-index的应用范围扩大了不少

      [注意]所有整数都可以作为z-index的值,包括负数。如果为元素指定一个负z-index值,会将其移到离读者更远的位置,会移到叠放栈的更低层

    堆叠规则

      对于CSS2.1来说,页面元素的堆叠规则如下图所示:

    定位元素的堆叠规则

      [1]对于定位元素(position不是static的元素)来说,不设置z-index或z-index相同时,后面元素覆盖前面元素

      [2]对于处于同一堆叠上下文中的同一层次的元素来说,默认z-index较大值覆盖z-index较小值

    堆叠上下文

      一旦为一个元素指定了z-index值(不是auto),该元素会建立自己的局部堆叠上下文。这意味着,元素的所有后代相对于该祖先元素都有其自己的叠放顺序

      [注意]auto值指当前堆叠上下文中生成的栈层次与其父框的层次相同,这个框不会建立新的局部叠放上下文。z-index:auto与z-index:0的值相等,但z-index:0会建立新的局部堆叠上下文

    默认样式

    <div class="box1">
        <ul class="list1">
            <li id="one">1</li>
            <li id="two">2</li>
            <li id="three">3</li>
            <li id="four">4</li>
        </ul>
        <ul class="list2">
            <li id="five">5</li>
            <li id="six">6</li>
        </ul>    
    </div>
    <div class="box2">
        <div id="seven">7</div>
        <div id="eight">8</div>
    </div>
    .box1{z-index: 1;}
    .box2{z-index: auto;}
    .list1{z-index: 2;}
    .list2{z-index: 1;}
    #one{z-index: -1;}
    #two{z-index: 1;}
    #three{z-index: 0;}
    #four{z-index: auto;}
    #five{z-index: 2;}
    #six{z-index: 1;}
    #seven{z-index: 2;}
    #eight{z-index: -1;}
    //堆叠顺序
    .box1                  1
    .box1 .list1           1,2
    .box1 .list1 #one      1,2,-1
    .box1 .list1 #two      1,2,1
    .box1 .list1 #three    1,2,0
    .box1 .list1 #four     1,2,auto
    .box1 .list2           1,1
    .box1 .list2 #five     1,1,2
    .box1 .list2 #six      1,1,1
    .box2                  auto
    .box2 #seven           auto,2
    .box2 #eight           auto,-1

      [注意]auto,2和auto,-1相当于2和-1,因为auto代表未产生堆叠上下文。则#seven和#eight相当于和它们的父级.box2以及.box1处于同一层次

      元素不会叠放在其堆叠上下文(即定位父级z-index为数字值)的背景之下,但可以叠放在其内容之下;当元素没有处于堆叠上下文中,元素不会叠放在<body>元素的背景之下,但可以叠放在其内容之下

    兼容

    【1】IE7-浏览器z-index的默认值是0

      一般地,定位元素的z-index的默认值是auto,而IE7-浏览器定位元素的z-index的默认值是0,二者的区别于IE7-浏览器的定位元素会自动生成堆叠上下文

    div{
        position: absolute;
        border: 1px solid black;
    }    
    .div1{
        width: 300px;
        height: 100px;
        background-color: pink;
        z-index: 1;
    }
    .div2{
        background-color: lightgreen;
        top: 50px;
        left: 50px;
        width: 200px;
        height: 200px;
    }
    .in2{
        width: 100px;
        height: 150px;
        background-color: lightblue;
        z-index: 2;
        border: none;
    }
    <div class="div1"></div>
    <div class="div2">
        <div class="in2"></div>
    </div>

      一般地,div1的堆叠顺序为1;div2的堆叠顺序为auto;in2的堆叠顺序为auto,2相当于2。所以覆盖层次为in2 覆盖 div1 覆盖 div2。但在IE7-浏览器中,div1的堆叠顺序为1;div2的堆叠顺序为0;in2的堆叠顺序为0,2。所以覆盖层次为div1 覆盖 in2 覆盖 div2

      左边为其他浏览器图示,右边为IE7-浏览器图示

    【2】IE6-浏览器关于z-index的一个怪异bug

      当元素本身浮动且不是定位元素(position不是static),元素父级是relative,则在IE6-浏览器在无论该元素的父级的z-index如何设置都不起作用

    .div1{
        position: absolute;
        z-index: 1;
        width: 100px;
        height: 100px;
        background-color: pink;
    }
    .box{
        position: relative;
        z-index:2;
    }
    .div2{
        float: left;
        width: 150px;
        height: 50px;
        background-color: lightgreen;
    }
    <div class="div1"></div>
    <div class="box">
        <div class="div2"></div>    
    </div>

      左边是IE6浏览器结果,右边是其他浏览器结果

    解决方法

      [1]元素去除浮动

      [2]父级元素的相对定位改成绝对定位

      [3]元素添加position属性(static除外)

      以上三个方法任一方法都可以,其实就是在破坏bug成立的条件

    【3】IE6-浏览器下select的z-index无效而遮挡div

      IE6-浏览器下select设置z-index无效,且默认会堆叠在div上

    .box{
        left: 30px;
        z-index:2;
        position: absolute;
        width: 100px;
        height: 100px;
        background-color: pink;
    }
    select{
        width: 100px;
        position: absolute;
        z-index:1;
    }
    <div class="box"></div>
    <select name="select" id="slt1">
        <option value="1">第一项</option>
        <option value="2">第二项</option>
    </select>

      左边是IE6浏览器结果,右边是其他浏览器结果

    解决方法

      在IE6-浏览器中,虽然div无法覆盖select,但是iframe可以select。所以可以设置一个与div宽高相同的iframe。让div覆盖iframe,iframe覆盖select,最终达到select被div覆盖的效果

    iframe{
        left: 30px;
        position: absolute;
        width: 100px;
        height: 100px;
        z-index: 2;
    }
    <iframe src="#" frameborder="0"></iframe>
    <div class="box"></div>
    <select name="select" id="slt1">
        <option value="1">第一项</option>
        <option value="2">第二项</option>
    </select>

    CSS3

      CSS3的出现对过去的很多规则发出了挑战。对层叠上下文z-index的影响更加显著,主要包括以下8个属性

      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

      9、元素的mask属性不是none

      设置以上9个属性的任意一个,都和设置absolute类似,层叠上下文z-index会生效。下面以opacity透明度为例,进行说明

  • 相关阅读:
    react性能检测与优化
    react组件在项目中的应用(基础知识)
    前端性能优化
    我们一起来详细的了解react的语法以及组件的使用方法
    和我一起使用webpack构建react项目
    babel与ES6环境的搭建
    Razor 在JS中嵌入后台变量
    HttpClient + ASP.NET Web API, WCF之外的另一个选择
    《大型网站技术架构》读书笔记[3]
    Remote Desktop Connection Manager 多个远程管理
  • 原文地址:https://www.cnblogs.com/xiaohuochai/p/5304619.html
Copyright © 2011-2022 走看看