CSS-合理使用z-index控制盒子视轴高度,解决z-index失效

来源:互联网 发布:软件代码编写招聘 编辑:程序博客网 时间:2024/05/16 10:53

关于z-index我们的共识

共识一

首先,我们都同意,z-index对于普通盒子是无效的,这里的“普通盒子”是除了下文我会提到的“神奇盒子”外的所有盒子,至于什么是“神奇盒子”请慢慢看。 
对于普通盒子,不管z-index值如何,写在html文档中后面的块会在写在前面的盒子上面,float的盒子会在没有float的盒子上面,文字等inline、inline-block元素会在block元素的上面。

以下所有代码示例请查看github查看完整源码

    <div class="first">first div</div>    <div class="second">second div</div>    <div class="inline">inline div</div>    <div class="float_first">first float div</div>    <div class="float_second">second float div</div>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5
        div{            width: 100px;            height: 200px;            border: 2px solid silver;        }        .first{            background-color: blue;        }        .second{            background-color: red;        }        .inline{            display: inline-block;            background-color: pink;        }        .float_first{            float: left;            background-color: green;        }        .float_second{            float: left;            background-color: orange;        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

x轴、y轴位置我是在chrome中用margin-top负值和margin-left正值调的,结果如下: 
这里写图片描述 
不管我如何给first div加z-index,哪怕给个9999这么大值,second div还是在其上面,其他块同理,z-index不能影响上图视轴(z轴)顺序,html标签顺序会影响first div、second div及first float div、second float div视轴高低。所以说,z-index不是给这些盒子使用的。

共识二

对于受z-index控制的,姑且称之为“神奇”的盒子(其实就是很多博客说的 stacking context,层叠上下文 ),z-index值越大其视轴越高,离用户越近,最大的就在最上面,会遮挡其他神奇盒子。 
这点不用我举例吧,很多人都习惯写z-index:900这种样式,就是想让这个盒子在最上面,当又出现一个盒子,就不得不写z-index:901这种让人迷糊的样式。

两个共识引出的一个问题

了解以上两个共识以后,你有没有想过这个问题,那么z-index 负值 与 普通盒子们谁在上面呢?

神奇盒子(层叠上下文)与普通盒子的视轴排列

我首先想介绍下层叠上下文,也就是什么样的盒子是神奇的盒子。

具有哪些样式的盒子会成为神奇盒子(层叠上下文)

首先,我们最常见的定位不是static的盒子,是神奇盒子,其他创建神奇盒子的方式我引用的博客的总结,如下:

  • z-index值不为auto的flex项(父元素display:flex|inline-flex).
  • 元素的opacity值不是1.
  • 元素的transform值不是none.
  • 元素mix-blend-mode值不是normal.
  • 元素的filter值不是none.
  • 元素的isolation值是isolate.
  • will-change指定的属性值为上面任意一个。
  • 元素的-webkit-overflow-scrolling设为touch. 
    关于以上总结,我测试过 opacity和transform ,但引用博客博主靠谱,大家可以亲测下。其实,其他我没测也是因为不常用,大家有个印象就ok。

神奇盒子与普通盒子视轴高度

话不多说,上代码。

    <div class="block">block box</div>    <div class="absolute">absolute box</div>    <div class="negative">negative box</div>    <div class="positive">positive box</div>    <div class="float">float box</div>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5
        html{            padding: 200px;        }        div{            width: 200px;            height: 100px;            border: 5px solid silver;        }        .block{            background-color: green;        }        .absolute{            position: absolute;            background-color: blue;            margin-top: -60px;            margin-left: 40px;        }        .negative{            position: absolute;            background-color: red;            z-index: -1;            margin-top: -140px;            margin-left: -20px;        }        .positive{            position: absolute;            background-color: purple;            z-index: 1;            margin-top: -40px;            margin-left: 60px;        }        .float{            float: left;            background-color: pink;            margin-top: -80px;            margin-left: 20px;        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

结果: 
这里写图片描述 
结论: html -> z-index负值神奇盒子(绝对定位) -> 块状盒子 -> float 盒子 -> z-index auto或者0的神奇盒子(绝对定位) -> z-index正值神奇盒子(绝对定位),视轴越来越高。PS,inline或者inline-block盒子高于float盒子,但低于auto z-index神奇盒子,就是位于粉色和蓝色盒子之间。

关于这个结论,你可以这么考虑,在普通盒子视轴排列的基础上,神奇盒子可以根据z-index值自由穿梭于普通盒子上或下。

以上都是兄弟盒子之间的关系,父子盒子关系很容易理解,子盒子会高于父盒子,不然我们写的子块不都被父块覆盖了。如果我想知道子盒子与其父盒子的兄弟盒子的关系呢(子盒子与其伯伯盒子的关系)?

当讨论嵌套盒子视轴关系时需要注意的问题

这里我只想提醒大家,如果父盒子是神奇盒子,子盒子与其伯伯盒子(子盒子的父盒子的兄弟盒子)的视轴关系是由父盒子与这个伯伯盒子关系决定的。比如:

    <div class="father">fahter box <div class="son">son box</div></div>    <div class="brother">brother box</div>
  • 1
  • 2
  • 1
  • 2
        div{            width: 200px;            height: 100px;            border: 5px solid silver;            position: absolute;        }        .father{            background-color: red;            z-index: 0;        }        .brother{            background-color: blue;            z-index: 1;        }        .son{            background-color: yellow;            z-index: 999;            width: 100px;            height: 50px;        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

位置请用margin或top、left自己在chrome里调下,你会看到如下图: 
这里写图片描述

没错,son的z-index为999,但是居然不在最上面,最上面的是 z-index为1的div。这个时候请不要大叫 z-index 失效,这是正常表现。因为son的父盒子father是神奇盒子,它的z-index为0,所以son与brother的关系由father与brother的关系决定,显然father在下么,那son就得在下,不管你给它设多大的z-index。

一道关于z-index的面试题

最后,既然你已经耐心读到这了,我就给你出道题考考你。仅使用css如何让上图中的brother在son与father中间?也就是,仅使用css如何让一个盒子位于它的兄弟盒子与兄弟盒子的子盒子中间。 





答案 

div{width: 200px;height: 100px;border: 5px solid silver;}.father{background-color: red;}.brother{background-color: blue;z-index: 1;position: absolute;}.son{background-color: yellow;z-index: 999;width: 100px;height: 50px;position: absolute;}