你所不知道的 CSS 濾鏡技巧與細節,css濾鏡技巧細節
本文主要介紹 CSS 濾鏡的不常用用法,希望能給讀者帶來一些乾貨!
OK,下面直接進入本文。本文所描述的濾鏡,指的是 CSS3 出來後的濾鏡,不是 IE 系列時代的濾鏡,文法如下,還未接觸過這個屬性的可以先簡單到 MDN — filter 瞭解下:
```
{
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;
}
```
## 基本用法
先簡單看看幾種濾鏡的效果:

你可以通過 hover 取消濾鏡,觀察該濾鏡的效果。
簡單來說,CSS 濾鏡就是提供類似 PS 的圖形特效,像模糊,銳利化或元素變色等功能。通常被用於調整圖片,背景和邊界的渲染。本文就會圍繞這些濾鏡展開,看看具體能怎麼使用或者玩出什麼花活。

## 常用用法
既然是標題是你所不知道的技巧與細節,那麼比較常用的一些用法就不再贅述,通常我們見得比較多的 CSS 濾鏡用法有:
- 使用 `filter: blur()`產生毛半透明效果
- 使用 `filter: drop-shadow()`產生整體陰影製作效果
- 使用 `filter: opacity()`產生透明度
如果對上面的技巧不是很瞭解,可以稍稍百度Google一下,下文將由淺及深,介紹一些不大常見的濾鏡的具體用法及一些小細節:
## contrast/brightness — hover 增亮圖片
通常頁面上的按鈕,都會有 hover/active 的顏色變化,以增強與使用者的互動。但是一些圖片展示,則很少有 hover 的互動,運用` filter: contrast()`或者`filter: brightness()`可以在 hover 圖片的時候,調整圖片的對比圖或者亮度,達到聚焦使用者視野的目的。
`brightness表示亮度,contrast 表示對比。`
當然,這個方法同樣適用於按鈕,簡單的 CSS 代碼如下:
```
.btn:hover,
.img:hover {
transition: filter .3s;
filter: brightness(1.1) contrast(110%);
}
```


## blur — 產生映像陰影
通常而言,我們產生陰影的方式大多是 box-shadow 、filter: drop-shadow() 、text-shadow 。但是,使用它們產生陰影是陰影只能是單色的。
有讀者同學會問了,你這麼說,難道還可以產生漸層色的陰影不成?!

額,當然不行。

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

下面就利用濾鏡,給它添加一層與原圖顏色相仿的陰影製作效果,核心 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 (web前端學習交流群:328058344 禁止閑聊,非喜勿進!)
## blur混合 contrast產生融合效果
接下來介紹的這個,是本文的重點,模糊濾鏡疊加對比濾鏡產生的融合效果。讓你知道什麼是 CSS 黑科技!
單獨將兩個濾鏡拿出來,它們的作用分別是:
1. filter: blur(): 給映像設定高斯模糊效果。
2. filter: contrast(): 調整映像的對比。
但是,當他們“合體”的時候,產生了奇妙的融合現象,通過對比濾鏡把高斯模糊的模糊邊緣給幹掉,利用高斯模糊實現融合效果。
先來看一個簡單的例子:

仔細看兩圓相交的過程,在邊與邊接觸的時候,會產生一種邊界融合的效果。
上述效果的實現基於兩點:
1. 圖形是在被設定了 filter: contrast()的畫布背景上進行動畫的
2. 進行動畫的圖形被設定了 filter: blur()( 進行動畫的圖形的父元素需要是被設定了 filter: contrast()
的畫布)
意思是,上面兩圓運動的背後,其實是疊加了一張設定了 filter: contrast()
的大白色背景,而兩個圓形則被設定了 filter: blur()
,兩個條件缺一不可。
當然,背景色不一定是白色,我們稍稍修改上面的Demo,簡單的如下:

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

不用懷疑你的眼睛,上述 GIF 效果就是使用純 CSS 實現的。
核心還是 filter: contrast()
與 filter: blur()
配合使用,不過實現的過程也非常有趣,我們需要使用 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);
之後,為什麼純色黑色和黃色的中間,產生了一條紅色的邊框?
> 這裡我諮詢了幾個設計師、前端同事,得到的回覆大概是兩個不同濾鏡的色值處理演算法在邊界處疊加作用得到了另外一種顏色。(不一定準確,求賜教),在 PS 裡嘗試還原這個效果,但是 PS 沒有 contrast() 濾鏡,得到的效果偏差挺大的。
OK,繼續本文,接下來,我們只需要在火焰 .fire
這個 div 內部,用大量的黑色圓形,由下至上,無規律穿過火焰即可。由於濾鏡的融合效果,火焰效果隨之產生,這裡為了方便理解,我把背景色切換成白色,火焰動畫原理一看即懂:

## 文字融合動畫
另外,我們可以在動畫的過程中,動態改變元素濾鏡的 filter: blur()
的值。
利用這個方法,我們還可以設計一些文字融合的效果:


具體實現你可以看這裡:
> CodePen Demo — word animation | word filter(https://codepen.io/Chokcoco/pen/jLjNRj)
## 值得注意的細節點
動畫雖然美好,但是具體使用的過程中,仍然有一些需要注意的地方:
1. CSS 濾鏡可以給同個元素同時定義多個,例如 filter: contrast(150%) brightness(1.5)
,但是濾鏡的先後順序不同產生的效果也是不一樣的;
也就是說,使用 filter: contrast(150%) brightness(1.5)
和 filter: brightness(1.5) contrast(150%)
處理同一張圖片,得到的效果是不一樣的,原因在於濾鏡的色值處理演算法對圖片處理的先後順序。
2. 濾鏡動畫需要大量的計算,不斷的重繪頁面,屬於非常消耗效能的動畫,使用時要注意使用情境。記得開啟硬體加速及合理使用分層技術;
3. blur()混合 contrast()濾鏡效果,設定不同的顏色會產生不同的效果,這個顏色疊加的具體演算法本文作者暫時也不是很清楚,使用時比較好的方法是多嘗試不同顏色,觀察取最好的效果;
4. CSS3 filter 相容性不算太好,但是在移動端已經可以比較正常的使用,更為精確的相容性列表,查詢 Can i Use。