0%

z-index 跨级不生效

在CSS世界中,z-index属性和定位元素在一起可以控制z轴顺序。理论上,数值越大层级越高。但在实际使用中会有很多细节需要注意。

背景描述

在一个小程序项目中有这样的一个需求:页面包含一个元素A和一个列表B,需要实现列表B的一部分在元素A之上,一部分在元素A之下。
基于组件封装的思想,一般的做法是:元素A是一个组件,列表B是另外一个组件。但是在这种布局下,发现无论如何调整元素A、列表B以及子元素的z-index,都无法满足“列表B的一部分在元素A之上,一部分在元素A之下”的效果。

表现异常

图中的上半部分是预期表现,而下半部分是实际表现。可以看到,列表B要不整个在元素A之上,要不就是整个在元素A之下。

小程序代码片段

层叠上下文

上面的示例代码如下:

1
2
3
4
5
6
<view class="container">
<view wx:for="{{4}}" wx:key="*this" class="box box-{{index}}">
z-index: {{index}}
</view>
</view>
<canvas class="canvas" type="2d">z-index: 1</canvas>

其中containercanvas的样式如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
.container {
position: relative;
z-index: 1;
outline: 4rpx dashed gray;
margin-top: 100rpx;
}
.canvas {
position: absolute;
top: 100rpx;
left: 100rpx;
height: 200rpx;
width: 550rpx;
background: #f4e6ba;
z-index: 1;
}

可以看到,container元素和canvas元素都是拥有z-index属性的定位元素( position 的值为 relative 或 absolute )。因此container元素和canvas元素均是一个层叠上下文

关于层叠下上文,有如下一条规则:

每个层叠上下文都是自包含的:当一个元素的内容发生层叠后,该元素将被作为整体在父级层叠上下文中按顺序进行层叠。

因此,在这种布局模式下(列表B整体嵌套在一个view下,和元素A处于同一个父级下,且均为层叠上下文),则表现肯定是:列表B或者整个在元素A之上,或者整个在元素A之下。