为何z-index在该特定CSS场景下表现异常?技术咨询
z-index 堆叠行为深度解析
测试代码
CSS 代码
*{ padding: 0; margin: 0; box-sizing: border-box; } body{ height: 100vh; display: flex; justify-content: center; align-items: center; background-color: #141214; } .card{ /* position: relative; */ width: 350px; height: 450px; background-color: #282729; border-radius: 15px; z-index: 1; } .img{ position: relative; width: 80%; background-color: #AAA; /* z-index: 1; */ } .img::before{ position: absolute; content: ''; left: -70%; top: 10%; width: 350px; height: 350px; background-color: #9BDB23; z-index: -1; } img{ max-width: 100%; }
HTML 代码
<div class="card"> <div class="img"> <img src="shoes.png" alt="A Shoe"> </div> <div class="content"> <h3>Nike Shoes</h3> <div class="size"> <p>size</p> <a href="#" class="size">7</a> <a href="#" class="size">8</a> <a href="#" class="size">9</a> <a href="#" class="size">10</a> </div> <div class="color"> <p>color</p> <div class="color green"></div> <div class="color blue"></div> <div class="color red"></div> </div> <a href="#" class="buy">buy now</a> </div> </div>
疑问解答
1. 为什么.img::before设z-index: -1会在.card后方,而非.img后方?
核心是堆叠上下文的规则:
.img是position: relative但未设置非auto的z-index,无法创建独立堆叠上下文。.card设置了z-index: 1,即使没写position: relative,浏览器也会自动将其定位设为relative,同时创建独立堆叠上下文。- 绝对定位的
.img::before,其堆叠上下文由最近的、能创建堆叠上下文的定位祖先决定。因为.img没创建堆叠上下文,所以它的堆叠上下文是.card。z-index: -1会让它处于.card堆叠上下文的最底层,也就是.card元素后方。
如果想让它只在.img后方,给.img加z-index: 0即可——此时.img会创建自己的堆叠上下文,::before的z-index: -1就会相对于.img生效,被压在.img下方。
2. .img::before设z-index: -1且.card设z-index: 1时,为什么会在.img和.content后方?
.card的z-index: 1创建了堆叠上下文,.img和.content作为它的子元素,默认按DOM顺序堆叠(.img在前,.content在后,所以.content在.img上方)。.img::before的堆叠上下文是.card,z-index: -1的层级比所有默认z-index: auto的子元素(.img、.content)都低,自然会被这两个元素覆盖。
3. .img::before设z-index: -1、.card可选z-index:1且.img设z-index:1时,为什么::before在其他元素后方但位于.img上方?
- 当
.img设置z-index:1时,它创建了自己的堆叠上下文,此时.img::before的堆叠上下文变为.img,不再是.card。 - 在
.img的堆叠上下文内部,层级顺序从低到高为:.img的背景/边框 →z-index: -1的::before→z-index: auto的<img>标签。所以绿色的::before会显示在.img的灰色背景上方,但在鞋子图片下方。 - 同时,
.img的z-index:1相对于.card的上下文(如果.card也设了z-index:1),.img层级高于.card背景,但.content作为.card子元素,DOM顺序在.img之后,所以.content在.img上方,最终::before会被.content覆盖,呈现出“在其他元素(.card、.content)后方,但在.img背景上方”的效果。
内容的提问来源于stack exchange,提问作者Anurag Gupta
相关产品推荐
相关产品推荐

