backdrop-filter属性导致fixed定位失效

backdrop-filter属性可以让一个元素后面区域添加图形效果(如模糊或颜色偏移),因为它适用于元素背后的所有元素,为了看到效果,必须使元素或其背景至少部分透明

不使用backdrop-filter属性时

<div class="container">
  <div class="child"></div>
</div>
.container {
  width: 10vw;
  height: 10vw;
  background-color: rgba(255, 100, 100, 0.8);
}
.child {
  position: fixed;
  top: 1vw;
  left: 1vw;
  right: 1vw;
  bottom: 1vw;
  background-color: rgba(100, 100, 255, 0.8);
}
此时子元素.child的固定定位是相对于浏览器窗口定位的

当使用backdrop-filter属性时

<div class="container">
  <div class="child"></div>
</div>
.container {
  width: 10vw;
  height: 10vw;
  background-color: rgba(255, 100, 100, 0.8);
  backdrop-filter: blur(20px);
}
.child {
  position: fixed;
  top: 1vw;
  left: 1vw;
  right: 1vw;
  bottom: 1vw;
  background-color: rgba(100, 100, 255, 0.8);
}
此时子元素.child的固定定位是相对于使用backdrop-filter属性的父元素定位的

因为:使用backdrop-filter属性导致position: fixed;定位失效了

position: fixed的元素相对于屏幕视口(viewport)的位置来指定其位置,并且元素的位置在屏幕滚动时不会改变,但是,在许多特定的场合,指定了position:fixed的元素却无法相对于屏幕视口进行定位
解决方案一:使用伪元素
将backdrop-filter属性添加到伪元素上,通过修改z-index层级关系,实现同样的效果
.container {
  width: 10vw;
  height: 10vw;
  background-color: rgba(255, 100, 100, 0.8);
  position: relative;
}
.container::before {
  content: '';
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  backdrop-filter: blur(20px);
}
.child {
  position: fixed;
  top: 1vw;
  left: 1vw;
  right: 1vw;
  bottom: 1vw;
  background-color: rgba(100, 100, 255, 0.8);
}

解决方案二:计算

原本使用鼠标的事件对象e,e.pageX、e.pageY就可以获取到位置并实现固定定位,但由于使用了backkdrop-filter属性,使其相对于父元素定位了,那么这样获取到的位置也就不对了,需要计算相对于父元素的位置,从而相对于父元素实现定位

这种方法由于需要针对不同的浏览器进行处理,并且不清楚哪些浏览器会受影响,所以不太推荐

const ua = navigator.userAgent;
// 在IE浏览器和safari浏览器中fixed定位不受backkdrop-filter的影响
const isSpecialBrowser = /Safari|MSIE|Trident\//i.test(ua) && !/Chrome/.test(ua);
const chatToolsContainer = document.getElementById('chat-tools-container');
if(chatToolsContainer && !isSpecialBrowser) {
  const chatToolsContainerRect = chatToolsContainer.getBoundingClientRect();
  this.tipTop = e.pageY - chatToolsContainerRect.top + 20;
  this.tipLeft = e.pageX - chatToolsContainerRect.left + 10;
} else {
  this.tipTop = e.pageY + 20;
  this.tipLeft = e.pageX + 10;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值