屏幕是一个二维平面,然而HTML元素却是排列在三维坐标系中(x,y,z),如果元素脱离文档流浮动的话(如设置float,position),就会出现层叠的现象。一开始,我们想要哪个元素出现在z轴最上面,一般就设置z-index的大小就行。但有时候却出现z-index无效的现象。如某个元素的z-index明明比另一个元素大,却仍被另个元素覆盖了。这是因为元素在z轴上出现的顺序并不是由z-index决定的,而是在某种情况下才受到z-index大小的影响。我根据某个大神的博客,简化了他的内容,相信看了,应该能完全了解层叠的种种问题,并可以熟练应用,而且忘记某个细节时,查阅起来也比较方便。
首先,我们用一个名词来描述一个元素在z轴上出现的顺序:层叠等级。也就是说,层叠等级越高,该元素就出现在z轴的越上面。
这时候,我们想控制两个元素,控制他们的出现的顺序,只要控制他们的层叠等级就行了。但如最初说的,层叠等级不是由z-index决定的,那是什么呢。
层叠等级是由层叠顺序决定的。
层叠顺序 ,描述的是元素在同一个层叠上下文(下面会解释)中的z轴上出现的顺序,从z轴的底部开始,共有七种层叠顺序:
1.背景和边框:形成层叠上下文的元素的背景和边框。
2.负z-index值:层叠上下文内有着负z-index值的定位子元素,负的越大层叠等级越低;
3.块级盒:文档流中块级、非定位子元素;
4.浮动盒:非定位浮动元素;
5.行内盒:文档流中行内、非定位子元素;
6.z-index: 0:z-index为0或auto的定位元素, 这些元素形成了新的层叠上下文;
7.正z-index值:z-index 为正的定位元素,正的越大层叠等级越高;
也就是说,只要记住这七个层叠顺序,我们就可以随意控制元素的层叠等级了,从而控制元素出现在z轴上的顺序,会不会被另一个元素覆盖。
而当两个元素处于同一个层叠顺序的话(比如处于6这个顺序),他们的层叠等级则由他们在html中出现的顺序决定,出现越后,层叠等级越高。
可以看出,层叠顺序决定层叠等级,决定两个元素在z轴出现的顺序,我们只需比较其层叠等级即可,但层叠等级只有在同一个
层叠上下文才有比较的意义,即层叠顺序只有在同一个层叠上下文才生效。
而
层叠上下文是什么呢,它也是个元素,但该元素具有以下特征:
根元素<html></html>
position值为absolute | relative,且z-index值不为 auto
position 值为 fixed | sticky
z-index 值不为 auto 的flex元素,即:父元素display: flex | inline-flex
opacity 属性值小于 1 的元素
transform 属性值不为 none的元素
(这里只列举出了部分常见的,剩下不常见的看大佬的原文)
我们可以想象层叠上下文其实就一个载体,在该载体上的元素(子元素)才可以根据层叠顺序比较层叠等级。
也就是说,当一个元素A所处的层叠上下文AF(父元素)比另一个元素B所处的层叠上下文BF层叠等级低的时候,A和B是没比较意义的,只需比较他们的父元素(AF的层叠等级比BF低),就可以判断元素A被元素B覆盖了。这也意味着,就算A的层叠等级比B大,也没有用。
可以总结:
层叠等级是由层叠上下文的层叠等级、层叠顺序、定位元素的z-index,html上出现的顺序共同决定的。是不是看起来很麻烦,但我们完全可以忽略其他的,只需要记住层叠顺序中的那个七个顺序即可,其他的自然就可以得从中得知了。简言之,层叠等级是由层叠顺序决定的
而实际操作中该怎么做呢,要比较两个元素的层叠等级:
1.找出他们的层叠上下文。
2.如果在同一个层叠上下文。
2.1比较他们的层叠顺序
2.1.1如果他们在同一个层叠顺序,则比较在html中出现的顺序。
2.1.1如果同属于第七个层叠顺序,则比较他们的z-index。
3.如果不在同一个层叠上下文。
3.1.比较他们所在的层叠上下文。
这是大佬的原文:
juejin.im/post/5ba4ef…
可能简化后还是看不明白(怪我),或者有其他的疑问,这里都可以看原文.
大佬写的一个比较好的例子:
codepen.io/SHERlocked9…,可以根据我刚才列举的步骤来尝试下。