Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

高级CSS filters #9

Open
airen opened this issue Aug 10, 2015 · 9 comments
Open

高级CSS filters #9

airen opened this issue Aug 10, 2015 · 9 comments

Comments

@airen
Copy link
Contributor

airen commented Aug 10, 2015

在iOS系统上常常能看到高斯模糊(Gaussian Blur)效果,而这种效果早期使用CSS来实现是较为痛苦的一件事情。其实,早上2011年,浏览器就开始对CSS filters规范有所支持。也就是说在2011年浏览器就可以实现Filters效果。但这种效果基本上都只运用在SVG上(只有SVG支持Filter效果),而且只有Firefox浏览器支持,并且只能运用在HTML上。这也造就CSS要实现Filters效果是非常蛋疼的一件事情。比如说下图的效果:

高级CSS filters
高级CSS filters

对于做原生开发的同学来说,这样的效果并不是难事(可以点击这里这里查看相关讨论),而我们是一名CSSer,我们坚持要用CSS来完成。

可能你首先想到的是CSS的filter中的blur(),或者SVG中的filter。但这些都不是新技术,而且到处也常见:

这些都不是CSS的新特性,那什么是新特性呢?不知道你是否有留意到@Johan在《Safari 9中有哪些新特性》一文中首先介绍的就是一个**Backdrop filters**,而且在@iamvdo的《高级CSS filters》对backdrop-filter属性做了详细的介绍。那么今天在这篇文章我们一起来看看通过哪些CSS的新特性可以实现类似iOS系统中那种高斯模糊效果。

backdrop-filter

backdrop-filter是在Filter Level2提出来的。其取值和filter Level1filter属性的属性值一样,包括:

其效果如下:

CSS filter

既然backdrop-filter整出的效果和filter没有差别,那还整个新属性出来,这不蛋疼?其实否也,你是否有发现过,最早在SVG上得到的filter效果,只能使用在SVG元素上;而filter使用在元素上,会直接影响其后代所有元素。那么问题来了,如果只需要对元素的背景做filter效果,怎么破。这个时候就突显了backdrop-filter的重要性。首先来看一个@iamvdo录制的效果视频:

在线DEMO:

<iframe id="XbGeej" src="http://codepen.io/airen/embed/XbGeej?XbGeej=300&theme-id=0&slug-hash=XbGeej&default-tab=result&user=airen" scrolling="no" frameborder="0" height="300" allowtransparency="true" allowfullscreen="true" class="cp_embed_iframe undefined" style="width: 100%; overflow: hidden;"></iframe>

注:在你的浏览器中你是看不到有任何效果,因为到目前为止仅有Safari 9浏览器支持,如果您想在浏览器中看到相应的效果,可以下载Webkit Nightly浏览器。

回过头来,其主要在#elem中使用了:

background: rgba(0,0,0,.2);
backdrop-filter: blur(2px) hue-rotate(180deg);

那么使用backdrop-filter可以实现我们一直无法实现的高斯模糊效果。

.header {
    background-color: rgba(255,255,255,.6);
    backdrop-filter: blur(5px)
}

每一个元素到达顶部header下面都会有一个blur(5px)的高斯模糊效果。

<iframe id="gpEGjZ" src="http://codepen.io/airen/embed/gpEGjZ?gpEGjZ=400&theme-id=0&slug-hash=gpEGjZ&default-tab=result&user=airen" scrolling="no" frameborder="0" height="400" allowtransparency="true" allowfullscreen="true" class="cp_embed_iframe undefined" style="width: 100%; overflow: hidden;"></iframe>

在上面的示例中,使用了@supports属性来做一个条件判断,当浏览器支持backdrop-filter属性,就有效果:

@supports (-webkit-backdrop-filter: none) {
  .Box-header {
      background: rgba(255,255,255,.6);
      -webkit-backdrop-filter: brightness(1.5) blur(4px);
  }
}

下面的GIF图展示了案例的真实效果

CSS filters

backdrop-filter除了可以实现类似iOS系统上的高斯模糊效果之外,还可以实现一些其它效果,比如说提高图像上的文本的可读性效果,而且还可以结合多个backdrop-filter属性值,可以实现类似于CSS混合模式的图片合层效果。

CSS filters

使用backdrop-filter事项

在使用backdrop-filter时,有一些小细节需要注意:

  • 运用backdrop-filter元素的背景应该使用半透明,不然永远看不到效果
  • backdrop-filter属性和裁剪属性(如border-radiusmaskclip-path等)结全在一起使用时,会有Bug产生
  • backdrop-filter可以创建一个堆栈文本(Stacking Context),类似于opacity属性一样
  • 可以配合动画属性animation一起使用
  • 到目前为止,仅有Safari浏览器支持,而且还需要添加前缀:-webkit-backdrop-filter,如果你使用autoprefixer这样的插件,无需考虑前缀相关事项

浏览器兼容性

可以通过CanIUse查看各浏览器厂商对backdrop-filter的兼容:

<iframe src="http://caniuse.com/css-backdrop-filter/embed" scrolling="no" frameborder="0" height="300" allowtransparency="true" allowfullscreen="true" style="width: 100%; overflow: hidden;"></iframe>

filter()

在2012年的一篇文章《CSS3 Filter的十种特效》介绍过filter属性。如果你使用过这个属性制作一些效果,一定有发现过,他会直接影响其后代元素,有点类似于opacity。但很多时候,只是希望元素的背景做效果调整,又不希望他会影响其他元素。而且又没有backdrop-filter属性的情形之下,filter()就显得格外的重要。

在继续往下阅读之前,你要注意一点,filter()并不等于以前介绍过的filter属性。简单的理解,一个是函数,一个是属性。那么我们今天要说的是filter()函数。为了能更好的与filter属性区分,filter()函数接受两个参数:

filter(<url>, <filter-function-list>)

其中<url>是指一个图像,<filter-function-list>是一个过滤器。这两者结合在一起将会返回一个处理过的新图像。如:

.element {
    background: filter(url(path/to/img.jpg), blur(5px));
}

因此,你可以给图片使用过滤效果,然后填充到元素中,比如background-filterbackground-opacitybackground-blur等等。如下图所示:

CSS Filters

上图展示了,给背景图使用了不同过滤属性得到的不同效果。效果是很完美,但是浏览器对其支持力度相当的差,到目前为止,也仅有Safari 9支持。

注意事项

值得一提的是,backdrop-filterfilter()可以使用CSS3的transitionanimation实现一些圆滑的过度效果或动画,甚至还可以使用JavaScript。

比如下图所示的一个效果:

CSS Filters

总结

虽然使用SVG或者CSS3的filter属性能实现类似的效果,但我还是非常的期待浏览器能支持backdrop-filterfilter()函数的特性。这样可以通过一行简单的CSS代码就能实现很多特殊(以前依赖于图片)效果。当然,这些特性能让我们快速实现需要的一些特殊效果,但在性能上会有很大的影响,根据以前使用filter属性的经验来看,这两个属性对性能的影响也将不小。

除此之外,虽然浏览器支持力度很小,但在iOS系统上我们即将可以使用这样的特性。最常见的一个,可以拿这两个特性实现高斯模糊的效果。

特别声明:本文图片、视频与案例都源自于@iamvdo的《高级CSS filters》一文。

@Horve
Copy link

Horve commented Aug 10, 2015

@yisibl
Copy link

yisibl commented Aug 19, 2015

大漠老师不仅人长的帅,文章写的也帅!

@leinue
Copy link

leinue commented Nov 19, 2015

不错

@lpgray
Copy link

lpgray commented Dec 10, 2015

在优雅降级原则基础上,这个属性很有意义

@king-king
Copy link

或者jser也能用js写,不过canvas写滤镜对性能影响较大

@mhxy13867806343
Copy link

学习了!

@yangshengjin
Copy link

yangshengjin commented May 26, 2023 via email

@miki-long
Copy link

miki-long commented May 26, 2023 via email

@XurryAli
Copy link

XurryAli commented May 26, 2023 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants