当多个 `position: sticky` 父元素中嵌套 `position: absolute` 子元素时,因粘性定位触发新的层叠上下文,导致后出现的父元素默认覆盖前者的子元素;需通过差异化设置 `z-index`(如 `:first-of-type` 和 `:last-of-type`)显式控制各父容器的堆叠层级。
在 SCSS(或 CSS)布局中,position: sticky 不仅影响滚动行为,还会隐式创建新的层叠上下文(stacking context)——这是本问题的根本原因。一旦父元素成为独立的层叠上下文,其内部 z-index 仅在该上下文内生效,而不同 .parent 元素之间的层叠顺序则由它们自身在文档流中的 z-index 值决定(而非子元素的 z-index)。因此,即使 .wrap 设置了 z-index: 1,若第二个 .parent 的层叠上下文整体“浮”在第一个之上,红色块仍会被遮挡。
由于无法修改 position: sticky 属性,也不能将 .wrap 移出父容器(需求限定为 absolute 且必须位于 .parent 内),最直接有效的方案是差异化控制各 .parent 自身的层叠优先级:
.parent {
width: 100px;
height: 50px;
background-color: blue;
position: sticky;
top: 0; // 推荐显式声明 top,确保 sticky 行为明确
border: 1px solid white;
.wrap {
position: absolute;
top: -5px;
left: -5px;
z-index: 1; // 在当前 parent 上下文中置顶
width: 50px;
height: 210px;
background-color: red;
}
&:first-of-type {
z-index: 2; // 保证第一个 parent 整体层级最高
}
&:nth-of-type(2) {
z-index: 0; // 第二个 parent 层级低于第一个,使其“退后”
}
}? 关键说明:z-index 只对已定位元素(即 position 为 relative/absolute/sticky/fixed)生效。此处 .parent 是 sticky,因此 z-index 有效,并决定了它在整个页面层叠顺序中的位置。
(n) 等伪类比硬编码类名更健壮,适合动态渲染场景;Sticky 元素天然创建层叠上下文,子元素的 z-index 无法跨上下文竞争。破局关键在于:主动管理父容器自身的 z-index 序列,而非仅聚焦于子元素。这一原则同样适用于模态框(modal)、悬浮菜单、吸顶导航等复杂 sticky 场景——只要结构受限,层级控制就必须从“容器维度”入手。