z-index是我们以前相对比较经常使用的一个语法了,看起来比较简单的样子,实际上还真不难,由于这东西跟以前讲的vertical-align不同,这个比较符合我们的认知。css
好了,不废话,开始我们的正式话题。html
首先呢?我们先要了解一下层叠上下文(stack context)是什么呢,其实通俗来说,就是你看电脑的这个方向的一个显示顺序,好比说,桌子上有一大堆纸,你对着它看的话,每一张纸,实际上你就能够理解为一个层叠上下文中的一个层叠顺序(stack level),你能看到的,每每是最靠前的那几张纸,后面的都被遮挡住了。前端
那么,首先最简单的一点。若是有有一摞的彻底重合的值,你能看到的,每每都是最靠上的那张纸,也就是离你眼睛最近的那一张。然而对于我们的z-index来讲呢,值越大,也就至关于离你眼睛越近。在纸张里的位置越靠上。 因此说,下面的代码,你应该一看就能知道,哪一个元素在哪一个元素的前面。css3
.paper1 { position: absolute; background-color: orange; z-index: 2; width: 100px; height: 100px; } .paper2 { position: absolute; background-color: gray; z-index: 5; width: 50px; height: 50px; } <div class="paper1"></div> <div class="paper2"></div>
下面是结果图,我想聪明如你,必定都猜到了。web
那么一个问题又来了,z-index大的,必定会遮盖住z-index小的吗?不废话,直接看下面的代码。浏览器
.paper1 { position: absolute; width: 100px; height: 100px; background: orange; z-index: 3; } .paper2 { position: absolute; width: 200px; height: 200px; background-color: aqua; z-index: 2; } .paper3 { position: absolute; top: 80px; width: 50px; height: 50px; background-color: red; z-index: 4; } <div class="paper1"></div> <div class="paper2"> <div class="paper3"></div> </div>
你以为哪一个的层级最高呢?来看一下最终运行的结果把。微信
居然不是.paper3在最上面,他彷佛被.paper1给挡住了,按理来讲,不是z-index越大的,层级越高吗?出现这种状况究竟是为何呢?flex
实际上,当z-index不为auto的时候,会自动建立一个它本身的层级上下文,也就是说,paper1和paper2是同级的,他们都在根环境上下文上。可是paper3呢,是在paper2的环境上下文中,由于paper1的层级要比paper2要高,因此paper3的z-index哪怕再大,实际上也依然会被paper1给挡住的。网站
那么,问题又来了,只有z-index不为auto时才会建立环境上下文吗?答案确定是否认的,实际上,我们平时用到的很多css属性,也会自动建立环境上下文,下面我们就看下mdn对这一块所列出来的一些属性(本文更新自2019.3.25,若是看到此文时已通过了好几个月,甚至是一两年,推荐看英mdn页面:https://developer.mozilla.org...)。google
层级上下文建立条件:
flex容器的子元素,其z-index值不为auto;
transform
filter
perspective、
clip-path
mask / mask-image / mask-border
看了上面的列表,应该会明白为何我用z-index的时候,都会加position: absolute了吧。
那么,若是z-index值相同时,会怎么显示呢?实际上,他会按照前后顺序,后面的会覆盖前面的。以下面的例子:
.paper1 { position: absolute; width: 100px; height: 100px; background: orange; z-index: 2; } .paper2 { position: absolute; width: 200px; height: 200px; background-color: aqua; z-index: 2; } <div class="paper2"></div> <div class="paper1"></div>
结果图以下:
那么若是此时吧两个div调换一下位置呢?那么就会以下图所示这样。
黄色的小块已经彻底被蓝色的给挡住了。不过若是是下面的代码形式呢?
.paper1 { display: inline-block; width: 100px; height: 100px; background: orange; } .paper2 { position: absolute; width: 200px; height: 200px; background-color: aqua; top: 0; } <div class="paper1"></div> <div class="paper2"></div>
此时的话,小黄块将会被遮挡住,不管paper1在paper2的前面和后面,最后的结果都依然是同样的。以下图所示
可是呢,假如给.paper1加入一个transform:scale(1)的话,他就会显示出来,依然会按照前后顺序,后面的先展现。
那么,为何会这样呢?
首先呢?在一个层叠上下文中,实际上里面不一样的元素是有不一样的层叠顺序的,实际上下图已经很好的说明了这一点,其从下往上依次为
background/border->负z-index->block块状水平盒子->float浮动元素->inline水平盒子->z-index:auto或者是z-index: 0->正z-index。
这个和我们平时开发的表现是一致的。可是请注意z-index:auto和z-index: 0;的层级。他其实是在inline水平元素的上面,由于定位元素,以及上面所列出来的css3的标签,不少都是默认的z-index: auto; 因此上上个例子中,绝对定位的元素,始终会覆盖其inline-block元素。可是呢,其inline-block元素因为新加了transform: scale(1)之后呢,实际上会默认一个z-index: auto; 因此他们俩实际上层级就一致了,所以他们也就是遵循后来居上的一个规则。谁在后面,谁就在靠上的位置。
同理,若是两个元素分别为z-index: 0和z-index: auto; 的话,他们俩也遵循后来居上的规则,他们俩惟一的区别,就是z-index: 0会新建一个层叠上下文,而z-index: auto;则不会;
另外,许多css3属性中,好比说虽然transform默认是z-index: auto,可是其实际上也会新建层叠上下文,因此,这块的话,你本身理解为有上面列出来的css3属性时,默认附带了一个z-index: 0就能够了。
固然了,我再写一个关于负z-index的例子,做为你们的一个小练习。不过我相信有了上面的铺垫后,这个对于你们来讲,应该就没有很大的问题了
.paper1 { display: inline-block; width: 100px; height: 100px; background: orange; } .paper2 { position: absolute; width: 50px; height: 50px; background-color: aqua; top: 0; z-index: -1; } <div class="paper1"> <div class="paper2"></div> </div>
此时结果以下图
此时的话呢,因为paper2的z-index为-1,因为paper1和paper2都在一个层叠上下文内(root),所以呢,paper2就天然的在paper1下面。也就如上图所示。
可是若是给.paper1增长了一个tranform: scale(1)呢,状况就会变得不太同样,以下图所示:
实际上就是由于增长了transform: scale(1)之后,实际上在paper1里面新建了一个层叠上下文,因此因为paper2是在paper1的层叠上下文里,因此它天然就显示出来了。不管其z-index值有多小。
好了,上面讲的也差很少了,不过依然是为了方便你们的理解,在最后,我简单的说一下其原理吧。
首先呢,其渲染树是一个深度优先的树结构,而后呢,先渲染的实际上会比后渲染的层级要更高一些,这个就跟我们用不一样的涂料刷墙同样,后刷的颜色老是会覆盖先刷的那些颜色,实际上网站渲染也是相似的。同时呢,在同级的时候,后面的要比前面的层级更高,实际上也是因为其遍历方式决定的,这个我就很少说了。
好了,完事了,谢谢你们观看,有什么问题想探讨的,或者我有什么错误遗漏的地方,都欢迎留言给我,谢谢你们
以为不错的话,能够关注微信公众号:干活技术,每周都有一篇前端相关原创干货小文章分享
推荐阅读:
https://developers.google.com...
https://www.w3.org/TR/css-pos...
张鑫旭《CSS世界》中z-index一章