CSS动画启用后z-index反转?伪元素阴影跑到主元素前方
问题:动画启用时伪元素阴影跑到元素前方
我有一个作为“球”的div,其::before伪元素设置z-index: -1,作为阴影置于div后方。页面中有一个按钮,点击后会为div添加上下弹跳的动画。问题在于:仅当动画启用时,作为阴影的伪元素会跑到div的前方。
已在Firefox 123、Google Chrome 122.0.6261.95和Microsoft Edge 121.0.2277.128中测试该示例,排除浏览器bug,应该是写法问题。
相关代码
HTML
<div ball></div> <button>Toggle animation</button>
CSS
*, *::before, *::after { position: relative; min-width: 0; padding: 0; margin: 0; box-sizing: border-box; } *::before, *::after { content: ''; position: absolute; } body { min-height: 100vh; background-color: rgba(0,0,0,.2); display: grid; place-items: center; } div[ball] { width: 10vw; aspect-ratio: 1; background-color: #fff; border-radius: 50%; --jump: 4vw; animation: var(--animation); animation-timing-function: ease-in-out; } div[ball]::before { width: 100%; height: 15%; bottom: -.5vw; background-color: rgba(0,0,0,.1); border-radius: 50%; z-index: -1; --jump: -4vw; animation: var(--animation); animation-timing-function: ease-in-out; } @keyframes ball-jump { 50% { transform: translate3d(0, calc(-1 * var(--jump)), 0); } } .disable-animation { --animation: ball-jump 1s infinite; }
JavaScript
document.querySelector("button").addEventListener("click", () => { document.body.classList.toggle("disable-animation"); })
问题分析与解决方案
原因
当元素应用transform(动画中使用了translate3d)时,会创建一个新的堆叠上下文。此时伪元素的z-index: -1仅在这个新的堆叠上下文中生效,不再相对于父元素本身,导致伪元素层级高于父元素。
修复方法
给父元素(div[ball])显式设置z-index值,确保它在自身创建的堆叠上下文里层级高于伪元素:
修改后的div[ball] CSS:
div[ball] { width: 10vw; aspect-ratio: 1; background-color: #fff; border-radius: 50%; --jump: 4vw; animation: var(--animation); animation-timing-function: ease-in-out; z-index: 1; /* 添加这一行 */ }
添加z-index:1后,父元素在堆叠上下文里的层级明确高于伪元素的z-index:-1,即使触发动画创建新的堆叠上下文,阴影伪元素也会始终处于div后方。
内容的提问来源于stack exchange,提问作者KimHansen
相关产品推荐
相关产品推荐

