关于z-index,每个人都会用,但大多人都不理解其真正的生效机制。最近做项目有很多用到z-index的地方,才发现以前用的一知半解,所以上网查了一些资料梳理了一下。下文参考自 !What No One Told You About Z-Index ,文中介绍了很多关于z-index使用的关键点。
关于z-index的生效机制并不复杂,但如果不花一点时间研究其特点,有很多关键点容易被忽略。
HTML文档中有三个div元素,每个div中存在一个span元素,三个span元素分别设置背景颜色为red,green,以及blue。然后每个span都设置为position: absolute,三个span的位置稍微错开以便可以仔细观察它们之间的堆叠顺序。然后将第一个span元素的z-index设置为1,其他两个不设置。具体代码如下:
<div> <span class="red">Red</span> </div> <div> <span class="green">Green</span> </div> <div> <span class="blue">Blue</span> </div>
.red, .green, .blue { position: absolute; width: 200px; height: 200px; } .red { background: red; z-index: 1; } .green { background: green; top: 50px; left: 50px; } .blue { background: blue; top: 100px; left: 100px; }
结果如下:
那么问题来了,尝试在不打破下述规则的前提下将red span置于blue和green span元素之下:
如果不了解z-index的一些特性,对于上述要求估计会有些烦恼。
在第一个div(也就是red span)上面添加一个值小于1的opacity属性,如下所示:
div:first-child { opacity: .99; }
然后就能看到惊讶的效果: opacity属性居然会影响元素的堆叠顺序,这个结果令人意想不到。
z-index表面上的规则似乎很简单,有一个更大z-index的元素会叠放在较小的z-index元素上面。但事实并非如此,这个规则只适用于一个相对的范围。
在HTML文档中有一个不变的堆叠准则,任何一个元素都可以叠放在其他元素之上或者之下,决定元素叠放顺序的规则其实很清晰。
1) z-index只在设置了position属性的元素上有效,没有position属性的元素上的z-index属性均不生效。
2) index值会产生堆叠上下文,堆叠上下文将在下一章中详细介绍。
拥有共同父元素的一组元素共同前移或者后移即构成了一个堆叠上下文。每个堆叠上下文有一个单一的根元素,当元素上形成一个新的堆叠上下文时,堆叠上下文中的所有子元素按照堆叠顺序被局限在一个固定的区域内。 一个堆叠上下文构成一个整体,其内部元素有相对不同的堆叠顺序,但与其他堆叠上下文比较时,只能整体上移或者下移。
通俗的讲,如果某个元素被置于其所在堆叠上下文的最底层,我们是没有办法让它显示在另一个拥有更高堆叠顺序的堆叠上下文的元素之上的,哪怕你将其z-index设置为无限大。
那构成一个堆叠上下文的规则是怎样的呢?有如下情况:
从底层到上层依次为:
在阐述完堆叠上下文的形成、堆叠上下文之间的堆叠规则,堆叠上下文内的堆叠顺序后,让我们回到文章最开始的问题。
起初元素的叠放顺序如下:
<div> //1 <span class="red"></span> //6 </div> <div> //2 <span class="green"><span> //4 </div> <div> //3 <span class="blue"></span> //5 </div>
当添加属性opacity: 0.99后,第一个div形成了一个新的堆叠上下文,red span成为了新的上下文中的第一个子元素。元素结构变为:
<div> //1 <span class="red"></span> //1.1 </div> <div> //2 <span class="green"><span> //4 </div> <div> //3 <span class="blue"></span> //5 </div>