结论:z-index 控制元素的层叠顺序,opacity 控制元素的透明度,两者解决的是不同问题【W1】。
1. z-index:谁显示在谁上面
.box-a {
position: absolute;
z-index: 2;
}
.box-b {
position: absolute;
z-index: 1;
}
当两个元素发生重叠时,通常 z-index 越大,元素越靠上。
但要注意:z-index 不是全局排名,它受到**层叠上下文(stacking context)**影响。
<div class="parent-a">
<div class="child">A</div>
</div>
<div class="parent-b">
<div class="child">B</div>
</div>
.parent-a {
position: relative;
z-index: 1;
}
.parent-b {
position: relative;
z-index: 2;
}
.child {
position: absolute;
z-index: 9999;
}
虽然 .parent-a .child 的 z-index 是 9999,但它仍可能被 .parent-b 整个层叠上下文压在下面。子元素无法突破父级层叠上下文。
2. opacity:元素有多透明
.box {
opacity: 0.5;
}
取值范围通常是:
opacity: 1; /* 完全不透明 */
opacity: 0.5; /* 半透明 */
opacity: 0; /* 完全透明,但仍存在 */
opacity: 0 的元素仍然可能:
- 占据布局空间;
- 接收鼠标事件;
- 参与层叠关系;
- 影响其子元素的显示效果。
如果希望它完全不参与交互,可以结合:
.hidden {
opacity: 0;
pointer-events: none;
}
3. 容易混淆的地方:opacity 会创建层叠上下文
当 opacity 小于 1 时,元素会创建新的 stacking context。因此,下面这段代码中,opacity 可能间接影响最终的绘制顺序:
.parent {
opacity: 0.99;
}
.child {
position: relative;
z-index: 9999;
}
这不是因为 opacity 比 z-index “优先级更高”,而是因为 .parent 创建了新的层叠上下文。透明度本身与 z-index 没有直接的优先级竞争【W2】【W4】。
对比
| 属性 | 作用 | 是否影响透明度 | 是否影响层叠顺序 |
|---|---|---|---|
z-index |
控制重叠元素的前后顺序 | 否 | 是 |
opacity |
控制元素及其子元素的透明度 | 是 | 间接影响,因为可能创建 stacking context |
实际排查覆盖问题时,我一般按这个顺序检查:
- 元素是否重叠;
position、z-index是否生效;- 父元素是否创建了 stacking context;
- 是否存在
opacity < 1、transform、filter、isolation等属性; - 是否被父级的层叠上下文限制。