为什么我写的z-index不生效?

前言相信大家在工作中都遇到过这样一些奇怪的问题:
1.为什么我写的z-index没有生效?
2.为什么z-index大的元素却没有盖住z-index小的元素?
3.如何让父元素盖住子元素呢?
以上这些问题都跟CSS层叠上下文有关,带着上面这些问题我们一起来了解一下什么是CSS层叠上下文,以及这些奇怪现象背后的原理!
如果这篇文章有帮助到你,?关注+点赞?鼓励一下作者,文章公众号首发,关注 前端南玖 第一时间获取最新文章~
什么是CSS层叠上下文?

层叠上下文是HTML元素的三维概念,这些HTML元素在一条假想的相对于面向(电脑屏幕的)视窗或者网页的用户的z轴上延伸,HTML元素依据其自身属性按照优先级顺序占用层叠上下文的空间 。
z轴在CSS2.1规范中,每个盒模型的位置是三维的,分别是平面画布上的X轴Y轴以及表示层叠的Z轴 。一般情况下 , 元素在页面上沿X轴Y轴平铺,我们察觉不到它们在Z轴上的层叠关系 。而一旦元素发生堆叠,这时就能发现某个元素可能覆盖了另一个元素或者被另一个元素覆盖 。
为什么我写的z-index不生效?

文章插图
我们可以这样来理解:
  • 层叠上下文是HTML元素的三维概念,可以想象为一条垂直于视窗的z轴
  • 当元素创建了重叠上下文时,这个元素就有了一个z轴
  • 如果内部的子元素发生重叠,会依据自身属性优先级顺序占用z轴(重叠上下文)上的空间
  • 优先级最大的元素排在最上面,离用户也最近
如何产生层叠上下文?了解了层叠上下文,我们还要知道层叠上下文是如何产生的 。
一般来讲有3种方法:
  • html中的根元素<html></html>本身就是层叠上下文,成为根层叠上下文
  • position属性为非static值并设置z-index属性为具体数值
  • 一些CSS3属性也能产生层叠上下文
    • 一个 flex 元素(flex item),且 z-index 值不为 “auto”,也就是父元素 display: flex|inline-flex
    • 元素的 opacity 属性值小于 1
    • 元素的 transform 属性值不为 “none”
    • 元素的 mix-blend-mode 属性值不为 “normal”
    • 元素的 isolation 属性被设置为 “isolate”
    • 在 mobile WebKit 和 Chrome 22+ 内核的浏览器中,position: fixed 总是创建一个新的层叠上下文, 即使 z-index 的值是 “auto”
    • 在 will-change 中指定了任意 CSS 属性,即便你没有定义该元素的这些属性
    • 元素的 -webkit-overflow-scrolling 属性被设置 “touch”
层叠等级与层叠顺序层叠等级
【为什么我写的z-index不生效?】层叠等级(stacking level , 叫“层叠级别”/“层叠水平”也行),它决定了同一个层叠上下文中元素在z轴上的显示顺序(层叠顺序)  , 也就是说普通元素的层叠水平优先由层叠上下文决定 。
层叠顺序
“层叠顺序”英文称作”stacking order”. 表示元素发生层叠时候有着特定的垂直显示顺序 , 注意 , 这里跟上面两个不一样,上面的层叠上下文和层叠水平是概念,而这里的层叠顺序是规则 。
从上面产生层叠上下文的方法,我们可以分为CSS2.1与CSS3两类,在CSS3出来之前,相信大家都看过下面这张图:
为什么我写的z-index不生效?

文章插图
看到这张图,相信大家最有疑问的是行内元素的层叠顺序要高于块级元素与浮动元素 。
OK,有疑问就动手实践一遍,看看是不是真是这样:
<style>  div {    width: 100px;    height: 100px;    border: 1px solid saddlebrown;}  .box1 {    position: relative;    z-index: -1;    background: violet;}  .box2 {    margin-top: -50px;    margin-left: 50px;    background: salmon;}  .box3 {    float: left;    margin-top: -50px;    margin-left: 100px;    background: wheat;}  .box4 {    display: inline-block;    background: greenyellow;    margin-left: -50px;}  .box5 {    position: relative;    z-index:0;    left: 200px;    top: -50px;    background: palevioletred;}  .box6 {    position: relative;    z-index: 1;    left: 250px;    top: -100px;    background: gold}</style></head><body>  <div class="box1">1定位z-index<0</div>  <div class="box2">2块级元素</div>  <div class="box3">3浮动</div>  <div class="box4">4行内元素</div>  <div class="box5">5定位z-index=0</div>  <div class="box6">6定位z-index>0</div></body>

推荐阅读