Fixed 定位的失效问题

通常情况下position: fixed元素相对于视口定位,但是某些情况下,比如祖先元素设置了transformfilterperspectivewill-change: transform的时候,子元素的固定定位会失效,不在相对于视口定位,而是相对于该祖先元素定位,约等于绝对定位。

比如:

html 复制代码
<div style="position: fixed; top: 50vh; right: 0; width: 10vh; height: 10vh; background-color: lightblue"></div>

<div style="transform: translate(0, 0); padding-top: 25vh">
  <div style="position: fixed; top: 10vh; width: 10vh; height: 10vh; background-color: lightcoral"></div>
</div>
<div style="filter: blur(0); padding-top: 25vh">
  <div style="position: fixed; top: 10vh; width: 10vh; height: 10vh; background-color: lightcyan"></div>
</div>
<div style="perspective: 0; padding-top: 25vh">
  <div style="position: fixed; top: 10vh; width: 10vh; height: 10vh; background-color: lightgoldenrodyellow"></div>
</div>
<div style="will-change: transform; padding-top: 25vh">
  <div style="position: fixed; top: 10vh; width: 10vh; height: 10vh; background-color: lightgray"></div>
</div>

第一个元素定位正常,但后面的元素定位异常,这是因为这些元素的父元素因为特定的 CSS 属性被放在新的图层之中。

一般情况下,当我们发现了固定定位异常时,排查祖先元素是否含有上述的 CSS 属性即可。但有一种情况,虽然在浏览器的 CSS 面板中看不到上述属性,但元素依然处于不同的图层中。这就是当元素被执行过animate且执行了上述 CSS 属性的动画。

比如:

html 复制代码
<div id="moving">
  <div style="position: fixed; top: 0; width: 10vh; height: 10vh; background-color: lightblue"></div>
</div>

<script>
  let moving = window.document.getElementById('moving');
  moving.animate([{ transform: 'translate(0, 0)' }, { transform: 'translate(0, 50vh)' }], { duration: 1000, fill: 'forwards' });
</script>

如果运行上面的代码,可以看到固定定位的元素在跟随父元素移动,同时此时看到浏览器的 CSS 面板中父元素并没有 transform 相关属性。

不得不说,好坑啊。

相关推荐
英俊潇洒美少年2 小时前
函数组件(Hooks)的 **10 大优点**
开发语言·javascript·react.js
haibindev2 小时前
把近5万个源文件喂给AI之前,我先做了一件事
java·前端·c++·ai编程·代码审计·架构分析
方安乐2 小时前
Javascript工具库:classnames
开发语言·javascript·ecmascript
labixiong2 小时前
React Hooks 闭包陷阱:高级场景与深度思考
前端·javascript·react.js
颜酱2 小时前
回溯算法专项突破练习(1)
javascript·后端·算法
早點睡3903 小时前
ReactNative项目OpenHarmony三方库集成实战:react-native-contacts
javascript·react native·react.js
☞无能盖世♛逞何英雄☜3 小时前
Echarts数据可视化应用
前端·信息可视化·echarts
2501_943610363 小时前
我爱导航系统美化版源码网址导航系统带后台-【全开源】
前端·后端·html·php
__Yvan3 小时前
Kotlin 的 ?.let{} ?: run{} 真的等价于 if-else 吗?
android·开发语言·前端·kotlin