傻傻分不清?深入探讨Filter和Backdrop-filter的相同点和不同点
时间:2023-03-16 22:23:46
科技观察
本文将深入探讨CSS中两个非常相似的属性——filter和backdrop-filter。它们都执行某些过滤功能,但它们之间肯定存在差异。那么,为什么在CSS中有一个过滤器和一个背景过滤器?带着这个疑问,我开始了今天的课文。filterVSbackdrop-filter在CSS中,有两个与过滤器相关的属性——filter和backdrop-filter。backdrop-filter[1]是较新规范引入的新属性,可以点击查看滤镜效果模块Level2。filter:该属性对元素应用模糊或颜色偏移等图形效果。background-filter:此属性允许您向元素后面的区域添加图形效果(例如模糊或颜色偏移)。它适用于元素后面的所有元素,为了看到效果,元素或其背景必须至少部分透明。注意两者的区别,filter作用于元素本身,而backdrop-filter作用于元素后面区域覆盖的所有元素。它们支持的过滤器类型:可以看到,两者支持的过滤器类型是完全一样的。话虽如此,它们之间必然存在诸多差异,让我们一一探讨。作用对象的区别backdrop-filter最常用的功能是实现毛玻璃效果。让我们通过实现磨砂玻璃效果来了解filter和backdrop-filter使用的一些区别。在backdrop-filter诞生之前,我们很难实现这样的毛玻璃效果:有了它,实现毛玻璃效果非常容易。看这段代码:Normal
filter
backdrop-filter .bg{background:url(image.png);&>div{width:300px;height:200px;background:rgba(255,255,255,.7);}.g-filter{filter:blur(6px);}.g-backdrop-filter{backdrop-filter:blur(6px);}}CodePenDemo--filter和backdrop-filter比较[2]filter和backdrop-filter最明显的区别是:filter作用于当前元素,它的后代元素也会继承这个属性backdrop-filter元素后面的所有元素仔细区分理解,一个是当前元素和它的后代元素,一个是元素后面的所有元素。明白了这一点,你就明白为什么会有filter和backdrop-filter了。效果上的差异下面我们来看一下实际使用和效果上的一些差异。比如我们要实现这样一张图片的maskHover效果:使用backdrop-filter就可以轻松做到,因为它是用来生成mask,作用于mask后面的元素的。核心伪代码如下:wallpaper-4.jpg);}div::before{content:"";position:absolute;top:0;left:0;bottom:0;right:0;backdrop-filter:grayscale(100%);transition:.3stransform;}div:hover::before{transform:translate(100%,0);}想想如果用filter怎么实现上面的效果?比较麻烦,因为滤镜是作用在元素上的,所以只能实现类似这样的Hover效果:上面两种效果DEMO:CodePen--filterVSbackdrop-filter[3]核心代码:div{filter:grayscale(100%);transition:.3sfilter;}div:hover{filter:grayscale(0);}通过这个例子,应该可以更好地理解它们之间的区别。性能上的差异写这篇文章的初衷是因为我认为filter和backdrop-filter之间实际上可能存在性能上的差异。但是由于我使用了多个DEMO验证,使用filter和backdrop-filter实现了相同的动画效果,获取了动画过程中页面的帧率变化。除了Chrome自带的页面帧率控制面板,还有一种方案是使用rAF来近似页面帧率。可以点击这里——Web动画帧率(FPS)计算[4]经过实际对比发现,两者在性能上其实并没有什么区别。(当然也可能是我的实验不够严谨,有更准确数据的同学欢迎指出)。因此,如果filter和backdrop-filter都可以达到同样的效果,仅从性能上看,两者在性能上不会有太大差异,二选一即可。背景根下一点很有趣。说话要小心点。当然这对filter和backdrop-filter也是一样的,即应用了filter和backdrop-filter(值不是none)的元素都会生成BackdropRoot。什么是背景根?(规范戳我——CSS草稿——BackdropRoot[5]),也就是我们常说的,生成自己的层叠上下文(StackingContext)。直接看它会带来什么问题:生成BackdropRoot的元素会使CSS3D失效。之前写过一个3D小球旋转动画,大致是这样的:这个Demo可以点这里:CodePenDemo-3D小球[6]:但是,如果我们在上面动画的容器中添加一个filter或者backdrop-filter:{filter:blur(1px);}整个3D动画会塌陷成2D动画:更具体的讨论可以看我的这篇文章——探索CSS混合模式导致的CSS3D失效问题\filter[7]带有过滤器和背景过滤器的元素将使内部固定定位失效。这个问题也是比较常见的问题。我们都知道position:fixed在CSS中是相对于屏幕视口定位的。但是作用于filter和backdrop-filter元素的元素会导致其内部position:fixed元素不再相对于屏幕视口定位,而是相对于BackdropRoot元素定位,其表现是定位通过position:fixed元素退化为position:absolute。当然,除了filter和backdrop-filter,CSS中目前还有7种定位position的方式:固定在元素内部,基于元素:transform-style:preserve-3d是为transform属性值为非的元素设置的nonewill-change中指定透视值不为none的元素。设置任何CSS属性。contain:paintfilter值不是none的元素不是。我的这篇文章--固定定位失败|uncontrolledposition:fixed[8]兼容性差异最后,我们来看一下兼容性差异。今天不管IE,filter的兼容性其实很好(2021-12-27):而dropback-filter一直没有得到Firefox系列的支持:所以,Firefox的后续支持一直阻碍着dropback-filter过滤器是在生产环境中使用的最重要的部分。只是从兼容性的角度来说,我们应该尽可能的选择filter来使用两者都能达到的效果。最后,本文到此结束,希望本文对你有所帮助:)参考文献[1]backdrop-filter:https://drafts.fxtf.org/filter-effects-2/#BackdropFilterProperty[2]CodePen演示——过滤器与背景过滤器:https://codepen.io/Chokcoco/pen/WNjebrr[3]CodePen——过滤器与背景过滤器:https://codepen.io/Chokcoco/pen/VwzQYRV[4】网页动画帧率(FPS)计算:https://github.com/chokcoco/cnblogsArticle/issues/17[5]CSSdraft--BackdropRoot:https://drafts.fxtf.org/filter-effects-2/#BackdropRoot[6]CodePen演示-3D球:https://codepen.io/Chokcoco/pen/JwdvmJ[7]ExploringCSSblendingmode\filterscauseCSS3Dinvalidation:https://github.com/chokcoco/iCSS/issues/41[8]固定定位无效|不受控制的位置:固定:https://github.com/chokcoco/iCSS/issues/24