你可能不知道的 CSS 濾鏡技巧與細(xì)節(jié)

承接上一篇你所不知道的 CSS 動畫技巧與細(xì)節(jié)[1],本文主要介紹 CSS 濾鏡的不常用用法,希望能給讀者帶來一些干貨!
OK,下面直接進(jìn)入正文。本文所描述的濾鏡,指的是 CSS3 出來后的濾鏡,不是 IE 系列時代的濾鏡,語法如下,還未接觸過這個屬性的可以先簡單到 MDN -- filter[2] 了解下:
{
????filter:?blur(5px);
????filter:?brightness(0.4);
????filter:?contrast(200%);
????filter:?drop-shadow(16px?16px?20px?blue);
????filter:?grayscale(50%);
????filter:?hue-rotate(90deg);
????filter:?invert(75%);
????filter:?opacity(25%);
????filter:?saturate(30%);
????filter:?sepia(60%);
????/*?Apply?multiple?filters?*/
????filter:?contrast(175%)?brightness(3%);
????/*?Global?values?*/
????filter:?inherit;
????filter:?initial;
????filter:?unset;
}
基本用法
先簡單看看幾種濾鏡的效果:

CodePen Demo -- Css3 filter [3]
你可以通過 hover 取消濾鏡,觀察該濾鏡的效果。
簡單來說,CSS 濾鏡就是提供類似 PS 的圖形特效,像模糊,銳化或元素變色等功能。通常被用于調(diào)整圖片,背景和邊界的渲染。本文就會圍繞這些濾鏡展開,看看具體能怎么使用或者玩出什么花活。
常用用法
既然是標(biāo)題是你所不知道的技巧與細(xì)節(jié),那么比較常用的一些用法就不再贅述,通常我們見得比較多的 CSS 濾鏡用法有:
使用 filter: blur()生成毛玻璃效果使用 filter: drop-shadow()生成整體陰影效果使用 filter: opacity()生成透明度
如果對上面的技巧不是很了解,可以稍稍百度谷歌一下,下文將由淺及深,介紹一些不大常見的濾鏡的具體用法及一些小細(xì)節(jié):
contrast/brightness -- hover 增亮圖片
通常頁面上的按鈕,都會有 hover/active 的顏色變化,以增強與用戶的交互。但是一些圖片展示,則很少有 hover 的交互,運用 filter: contrast() 或者 filter: brightness() 可以在 hover 圖片的時候,調(diào)整圖片的對比圖或者亮度,達(dá)到聚焦用戶視野的目的。
brightness表示亮度,contrast 表示對比度。
當(dāng)然,這個方法同樣適用于按鈕,簡單的 CSS 代碼如下:
.btn:hover,
.img:hover?{
????transition:?filter?.3s;
????filter:?brightness(1.1)?contrast(110%);
}

CodePen Demo -- CSS3 filter hover IMG[4]
blur -- 生成圖像陰影
通常而言,我們生成陰影的方式大多是 box-shadow 、filter: drop-shadow() 、text-shadow 。但是,使用它們生成的陰影只能是單色的。
有讀者同學(xué)會問了,你這么說,難道還可以生成漸變色的陰影不成?

額,當(dāng)然不行。

這個真不行,但是通過巧妙的利用 filter: blur 模糊濾鏡,我們可以假裝生成漸變色或者說是顏色豐富的陰影效果。
假設(shè)我們有下述這樣一張頭像圖片:

下面就利用濾鏡,給它添加一層與原圖顏色相仿的陰影效果,核心 CSS 代碼如下:
.avator?{
????position:?relative;
????background:?url($img)?no-repeat?center?center;
????background-size:?100%?100%;
????
????&::after?{
????????content:?"";
????????position:?absolute;
????????top:?10%;
????????width:?100%;
????????height:?100%;
????????background:?inherit;
????????background-size:?100%?100%;
????????filter:?blur(10px)?brightness(80%)?opacity(.8);
????????z-index:?-1;
????}
}
看看效果:

其簡單的原理就是,利用偽元素,生成一個與原圖一樣大小的新圖疊加在原圖之下,然后利用濾鏡模糊 filter: blur() 配合其他的亮度/對比度,透明度等濾鏡,制作出一個虛幻的影子,偽裝成原圖的陰影效果。
嗯,最重要的就是這一句 filter: blur(10px) brightness(80%) opacity(.8); 。
CodePen Demo -- filter create shadow[5]
blur 混合 contrast 產(chǎn)生融合效果
接下來介紹的這個,是本文的重點,模糊濾鏡疊加對比度濾鏡產(chǎn)生的融合效果。讓你知道什么是 CSS 黑科技!
單獨將兩個濾鏡拿出來,它們的作用分別是:
filter: blur():給圖像設(shè)置高斯模糊效果。filter: contrast():調(diào)整圖像的對比度。
但是,當(dāng)他們“合體”的時候,產(chǎn)生了奇妙的融合現(xiàn)象。
先來看一個簡單的例子:

CodePen Demo -- filter mix between blur and contrast[6]
仔細(xì)看兩圓相交的過程,在邊與邊接觸的時候,會產(chǎn)生一種邊界融合的效果,通過對比度濾鏡把高斯模糊的模糊邊緣給干掉,利用高斯模糊實現(xiàn)融合效果。
上述效果的實現(xiàn)基于兩點:
圖形是在被設(shè)置了 filter: contrast()的畫布背景上進(jìn)行動畫的進(jìn)行動畫的圖形被設(shè)置了 filter: blur()( 進(jìn)行動畫的圖形的父元素需要是被設(shè)置了filter: contrast()的畫布)
意思是,上面兩圓運動的背后,其實是疊加了一張設(shè)置了 filter: contrast() 的大白色背景,而兩個圓形則被設(shè)置了 filter: blur() ,兩個條件缺一不可。
當(dāng)然,背景色不一定是白色,我們稍稍修改上面的Demo,簡單的示意圖如下:

燃燒的火焰
好,上面介紹完原理,下面看看使用這個效果制作的一些強大 CSS 效果,其中最為驚艷的就是使用融合效果制作生成火焰,這個效果我最早是見于 Yusuke Nakaya[7] 這位作者:

不用懷疑你的眼睛,上述 GIF 效果就是使用純 CSS 實現(xiàn)的。
核心還是 filter: contrast() 與 filter: blur() 配合使用,不過實現(xiàn)的過程也非常有趣,我們需要使用 CSS 畫出一個火焰形狀。
火焰形狀 CSS 核心代碼如下:
.fire?{
????width:?0;
????height:?0;
????border-radius:?45%;
????box-sizing:?border-box;
????border:?100px?solid?#000;
????border-bottom:?100pxsolid?transparent;
????background-color:?#b5932f;
????transform:?scaleX(.4);
????filter:?blur(20px)?contrast(30);
}
大概是長這樣:

分解一下過程:

放在純黑的背景下,就得到了上述圖片的效果。
這里會有個很大的疑問,增加了
filter: blur(20px) contrast(30);之后,為什么純色黑色和黃色的中間,生成了一條紅色的邊框?
這里我咨詢了幾個設(shè)計師、前端同事,得到的答復(fù)大概是兩個不同濾鏡的色值處理算法在邊界處疊加作用得到了另外一種顏色。(不一定準(zhǔn)確,求賜教),在 PS 里嘗試還原這個效果,但是 PS 沒有 contrast() 濾鏡,得到的效果偏差挺大的。
OK,繼續(xù)正文,接下來,我們只需要在火焰 .fire 這個 div 內(nèi)部,用大量的黑色圓形,由下至上,無規(guī)律穿過火焰即可。由于濾鏡的融合效果,火焰效果隨之產(chǎn)生,這里為了方便理解,我把背景色切換成白色,火焰動畫原理一看即懂:

具體完整實現(xiàn)可以看這里:
CodePen Demo -- CSS fire | CSS filter mix[8]
文字融合動畫
另外,我們可以在動畫的過程中,動態(tài)改變元素濾鏡的 filter: blur() 的值。
利用這個方法,我們還可以設(shè)計一些文字融合的效果:


具體實現(xiàn)你可以看這里:
CodePen Demo -- word animation | word filter[9]
值得注意的細(xì)節(jié)點
動畫雖然美好,但是具體使用的過程中,仍然有一些需要注意的地方:
CSS 濾鏡可以給同個元素同時定義多個,例如 filter: contrast(150%) brightness(1.5),但是濾鏡的先后順序不同產(chǎn)生的效果也是不一樣的;
也就是說,使用
filter: contrast(150%) brightness(1.5)和filter: brightness(1.5) contrast(150%)處理同一張圖片,得到的效果是不一樣的,原因在于濾鏡的色值處理算法對圖片處理的先后順序。
濾鏡動畫需要大量的計算,不斷的重繪頁面,屬于非常消耗性能的動畫,使用時要注意使用場景。記得開啟硬件加速及合理使用分層技術(shù); blur()混合contrast()濾鏡效果,設(shè)置不同的顏色會產(chǎn)生不同的效果,這個顏色疊加的具體算法本文作者暫時也不是很清楚,使用時比較好的方法是多嘗試不同顏色,觀察取最好的效果;CSS3 filter 兼容性不算太好,但是在移動端已經(jīng)可以比較正常的使用,更為精確的兼容性列表,查詢 Can i Use[10]。
更新于 2017-09-20,關(guān)于 blur 與 contrast 的融合算法,可以看看我這位大腿同事給出的解釋:濾鏡算法以及WebGL實現(xiàn)[11]
結(jié)語
好了,本文到此結(jié)束,希望對你有幫助 :)
如果還有什么疑問或者建議,可以多多交流,原創(chuàng)文章,文筆有限,才疏學(xué)淺,文中若有不正之處,萬望告知。
文內(nèi)鏈接
你所不知道的 CSS 動畫技巧與細(xì)節(jié): https://github.com/chokcoco/iCSS/issues/27
[2]MDN -- filter: https://developer.mozilla.org/zh-CN/docs/Web/CSS/filter
[3]CodePen Demo -- Css3 filter : https://codepen.io/Chokcoco/pen/wrwbvG
[4]CodePen Demo -- CSS3 filter hover IMG: https://codepen.io/Chokcoco/pen/RLwbyr
[5]CodePen Demo -- filter create shadow: https://codepen.io/Chokcoco/pen/eGYYpo
[6]CodePen Demo -- filter mix between blur and contrast: https://codepen.io/Chokcoco/pen/QqWBqV
[7]Yusuke Nakaya: https://codepen.io/YusukeNakaya/pens/public/
[8]CodePen Demo -- CSS fire | CSS filter mix: https://codepen.io/Chokcoco/pen/GvbMmE
[9]CodePen Demo -- word animation | word filter: https://codepen.io/Chokcoco/pen/jLjNRj
[10]Can i Use: http://caniuse.com/#search=filter
[11]濾鏡算法以及WebGL實現(xiàn): https://github.com/newbieYoung/MarkdownNote/blob/1a8cebb645231c0f0dc08f285dbb10d6db2734a5/colorful-shadow.md
iCSS,不止于 CSS,歡迎關(guān)注?↓
最后
歡迎加我微信(winty230),拉你進(jìn)技術(shù)群,長期交流學(xué)習(xí)...
歡迎關(guān)注「前端Q」,認(rèn)真學(xué)前端,做個專業(yè)的技術(shù)人...


