overflow 使得 transform-style 失效了
这周做了一个需求,出现了 Bug,经排查后发现:
同一元素同时设置 overflow: hidden
和 transform-style: preserve-3d
样式,会使得后者失去 3D 效果,也就是相当于 transform-style: flat
。
下面用示例验证一下:
<div class="container"> <div class="rect red"></div> <div class="rect green"></div> </div>
.constainer
区域设置了 transform-style: preserve-3d
;.red
区域设置了 transform: translate3d(20px, 20px, 10px)
;.green
区域设置了 transform: translate3d(0, 0, 5px)
;
.container { margin: 0 auto; border-radius: 10px; padding: 10px; width: 200px; height: 200px; background: #f8f8f8; transform-style: preserve-3d; } .rect { box-sizing: border-box; border: 2px solid #000; border-radius: 4px; width: 100px; height: 100px; } .red { background: #f00; /* translateZ 为 10px */ transform: translate3d(20px, 20px, 10px); } .green { background: #0f0; /* translateZ 为 5px */ transform: translate3d(0, 0, 5px); }
由于红色区域与绿色区域置于 3D 空间中,其中红色在 Z 轴更上面,因此实际表现如下,与预期一致。
一旦,将 overflow: hidden
应用于 .container
,
.container { margin: 0 auto; border-radius: 10px; padding: 10px; width: 200px; height: 200px; background: #f8f8f8; transform-style: preserve-3d; /* 新增 */ overflow: hidden }
那么结果就...
在不同设备实际表现还不一样,应该是渲染内核实现不一致导致的。FireFox 浏览器同左边表现一样。
其中左边为「非预期效果」,右边为「预期效果」。
示例可看:CodePen
我们分析一下左边的原因:
我们知道,使用 transform
会使得元素创建一个「层叠上下文」,也就是说 .red
和 .green
是两个不同的层叠上下文。由于这里并没有使用 z-index
来控制元素的「层叠顺序」,加上 overflow: hidden
使得 transform-style: preserve-3d
失去了 3D 空间效果,因此无法通过 transform: translateZ()
的大小来控制层叠顺序。因此在文档流中遵循「后者居上」的原则,使得 .green
处于 .red
的上方(即左边的表现)。
因此,可得出结论:在「非 Webkit 内核」中,同一元素同时设置 overflow: hidden
和 transform-style: preserve-3d
样式,会使得后者失去 3D 效果,也就是相当于 transform-style: flat
。
注意,以上结论表述为「非 Webkit 内核」可能不严谨。原因是:以上 Chrome 为 Mac 平台的截图,查看了其 UA 是 Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36
标注的是 Webkit 内核,难道实际是 Google 的 Blink 内核(虽说 Blink 师出 Webkit)?如果是的话,表述就没问题了。
有时候,犯错了印象才会更加深刻...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论