前言
最近在找前端工作,笔试的时候发现有道题考z-index的题几个公司都有的笔试题中都有,本以为这类型的题目十拿九稳,谁知......卒。于是在网上学习了一遍,特意来记录一下,都是大白话,写给自己看;
先放个题目,过滤一下要看的同学
题目:写出6个div元素的堆叠顺序,最上面的在第一个位置,例如: .one .two .three .four .five .six(z-index)
html:
<div class="one">
<div class="two"></div>
<div class="three"></div>
</div>
<div class="four">
<div class="five"></div>
<div class="six"></div>
</div>
css :
.one {
position: relative;
z-index: 2;
.two {
z-index: 6;
}
.three {
position: absolute;
z-index: 5;
}
}
.four {
position: absolute;
z-index: 1;
.five {}
.six {
position: absolute;
top: 0;
left: 0;
z-index: -1;
}
}
当时看这道题感觉有点恼火,因为.one 和 .four是不重叠,但是知道考的是什么就可以;
答案是: .three .two .one .five .six .four,答对的同学可以绕道了;
解析如下:
1、 .one 和 .four 都是层叠上下文,但是.one的z-index的层级高,所以 .one > .four;
2、 .two 没有设置position, 所以即使设置了 z-index 还是个块状元素,设置了position和正z-index的three层级高于.two,子元素必定在父元素之上 ,所以 .three > .two > .one > .four
3、根据第二步,子元素必定在父元素之上,并且 块元素在z-index为负的元素上,所以 .three > .two > .one > .five > .six > .four;
要想完全理解一个东西,首先要明白它是什么,也就是它的定义。我们先看看上面提到的层叠上下文、层叠等级都是什么?
开局一张图

剩下全靠编,代码看这里;
层叠上下文
如果一个元素是层叠上下文元素,这个元素在Z轴上更靠近屏幕观察者。
z轴:用户眼睛到屏幕的线;
如何产生“层叠上下文”
层叠上下文也基本上是有一些特定的CSS属性创建的,一般有3种方法:
1、HTML中的根元素本身就具有层叠上下文,称为“根层叠上下文”。
2、普通元素设置position属性为非static值,并设置z-index属性为具体数值(不能为z-index:auto),产生层叠上下文。
3、 CSS3中的新属性也可以产生层叠上下文。
层叠顺序
层叠顺序 定义:所有的元素都会根据层叠等级来在z-轴上排序的规则。
就是开局图里的规则,大家都在一个div里,有些元素就是比其他元素要高,就是这个规则:
层叠上下文(border/background) < 负z-index
< block块状盒子
< 浮动的盒子
< inline/inline-block水平盒子
< z-index:auto 或者 z-index:0
< 正z-index(定位并设定了正的z-index值,z-index值越大 层级越高)
层叠顺序优先由其所在的层叠上下文(为什么是层叠上下文,而非父元素,后面有例子2有说明)决定。 层叠顺序的比较只有在当前层叠上下文元素中才有意义。不同层叠上下文中比较层叠等级是没有意义的。
例子:
<div class="one" style="position:absolute;z-index:2">
<div class="two"></div>
</div>
<div class="three" style="position:absolute;z-index:1">
<div class="four" style="position:absolute;z-index:9999"></div>
</div>
.four 无论设置多大的z-index都没意义,因为three决定了four的层叠等级;
内联元素的层叠顺序要比浮动元素和块状元素都高
内联元素如文字这些都是内容,只有在内联等级高于浮动块状这些元素时,文字等内容才会显示;因此一定要让内联优先;
层叠顺序的准则
1、还是开局图的规则,当有元素有明显的层叠顺序时,层叠顺序高的覆盖层级顺序小的;
2、当不同元素处于同一层级的顺序时,写在html节点后面的覆盖前面的;
3、当其父元素不是层叠上下文,那么子元素会继续往上找,直到找到层叠上下文(或者到html元素),在层叠上下文做顺序比;
4、position:fixed 会相对于html元素来做层叠上下文;
z-index
定义:z-index 属性指定了一个具有定位属性的元素及其子代元素的 z-order。 当元素之间重叠的时候,z-order 决定哪一个元素覆盖在其余元素的上方显示。 通常来说 z-index 较大的元素会覆盖较小的一个。
对于一个已经定位的元素(即position属性值不是static的元素),z-index 属性指定:
元素在当前堆叠上下文中的堆叠层级。
元素是否创建一个新的本地堆叠上下文。
1、同一层叠上下文
层叠级别大的显示在上面,级别小的显示在下面;
层叠级别中的两个元素,依据它们在HTML文档流中的顺序,写在后面的将会覆盖前面的。
2、不同层叠上下文
元素的显示顺序依据祖先的层叠级别来决定,与自身的层叠级别无关
例子
1、在两个同一层级的元素中,同样设置了position 和 z-index(产生上下文),此时其各自的子元素都要由其父元素的z-index决定是否更靠近观察者;
<div class="zindex_1">
<div class="zindex_4">z-index : 4</div>
</div>
<div class="zindex_2">
<div class="zindex_3">z:index : 3</div>
</div>
div {
width: 200px;
height: 200px;
position: absolute;
}
.zindex_1 {
z-index : 1;
.zindex_4 {
z-index : 4;
background: red;
}
}
.zindex_2 {
z-index : 1;
.zindex_3 {
z-index : 3;
left: 100px;
top: 100px;
background: blue;
}
}

2、只有当z-index不为auto时,才有层叠上下文。子元素会根据其层叠上下文比较。
<div class="zindex_auto_1" style="position:relative;z-index:auto">
<div class="zindex_3" style="position:absolute;z-index:3;width :200px;height: 200px;background: black"></div>
</div>
<div class="zindex_auto_2" style="position:relative;z-index:auto">
<div class="zindex_4" style="position:absolute;z-index:2;width :200px;height: 200px;background: red;margin: -150px 0 0 50px;"></div>
</div>

此时的.zindex_auto_1 和 .zindex_auto_2 都不是层叠上下文,.zindex_3 和 .zindex_4 再往上找到层叠上下文,在找到html元素后,在html对比z-index,.zindex_3的z-index高,所以盖住zindex-4;
补充一下CSS3与新时代的层叠上下文
张老师写的很好了;
拓展阅读:深入理解CSS中的层叠上下文和层叠顺序
总结
- 先比较父元素,再比较子元素;
- 当子元素设置了position 和 index , 但其父元素不产生层叠上下文时,子元素时处于根层叠上下文(
<html></html>)中,此时会和同层级的比较; - 同级顺序时,后面的覆盖前面的;
- z-index : auto 不会使元素变为层叠上下文;
参考
1、深入理解CSS中的层叠上下文和层叠顺序 我自己记录的时候是没有层叠水平这个概念的;
2、z-index MDN文档叫堆叠,而不是层叠