CSS filter有哪些神奇用途

來源 | https://www.cnblogs.com/dragonir/p/14807272.html
作者 | dragonir
背景
基本概念
filter: <filter-function> [<filter-function>]* | nonefilter: url(file.svg#filter-element-id)
<filter-function> 可以用于 filter 和 backdrop-filter 屬性。它的數(shù)據(jù)類型由下列過濾器函數(shù)之一指定。每個函數(shù)需要一個參數(shù),如果參數(shù)無效,則濾鏡不會生效。以下是對濾鏡函數(shù)含義的解釋:
blur():模糊圖像
brightness() :讓圖像更明亮或更暗淡
contrast():增加或減少圖像的對比度
drop-shadow():在圖像后方應用投影
grayscale():將圖像轉(zhuǎn)為灰度圖
hue-rotate():改變圖像的整體色調(diào)
invert():反轉(zhuǎn)圖像顏色
opacity():改變圖像透明度
saturate():超飽和或去飽和輸入的圖像
sepia():將圖像轉(zhuǎn)為棕褐色
用法示例:
/* 使用SVG filter */filter: url("filters.svg#filter-id");/* 使用filter函數(shù) */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%);/* 多個filter */filter: contrast(175%) brightness(3%);/* 不使用filter */filter: none;/* 全局變量 */filter: inherit;filter: initial;filter: unset;

應用案例
更加智能的陰影效果
在給元素添加陰影的時候,我們一般采用 box-shadow 屬性,通過 box-shadow(x偏移, y偏移, 模糊大小, 陰影大小, 色值, inset) 的語法形式很容易為元素添加陰影效果,但 box-shadow 也有一個缺點,就是在給透明圖片添加陰影效果時,無法穿透元素,只能添加到透明圖片元素的盒模型上。
這個時候,filter 屬性的 drop-shadow 方法就能很好的解決這個問題,用它添加的陰影可以穿透元素,而不是添加到元素的盒模型邊框上。
drop-shadow 添加的陰影除了可以穿透透明元素外,陰影效果和 box-shadow 是相同的,如果瀏覽器支持硬件加速的話,使用 filter 添加的陰影效果會更加逼真。
drop-shadow 語法如下(它除了不支持設置 inset,其他和 box-shadow 是完全相同的):
filter: drop-shadow(x偏移, y偏移, 模糊大小, 色值);
如:
filter: drop-shadow(1px 1px 15px rgba(0, 0, 0, .5));下圖是分別使用 box-shadow 和 filter: drop-shadow 為透明元素添加陰影的對比:

<img src="futurama.png" /><img src="futurama.png" />
.box-shadow {box-shadow: 1px 1px 15px rgba(0, 0, 0, .5);}.drop-shadow {filter: drop-shadow(1px 1px 15px rgba(0, 0, 0, .5));}
元素、網(wǎng)頁置灰
發(fā)生重大災害事故或其他哀悼日時,國企政府網(wǎng)站往往有網(wǎng)頁全部置灰的需求。或者很多網(wǎng)頁中有鼠標 hover 懸浮到灰色元素上時變成彩色的樣式效果。
此時就可以使用 filter 屬性的 grayscale 方法實現(xiàn),它可以調(diào)整元素灰度,通過給頁面元素設置 filter: grayscale(100%) 就可將頁面元素置灰。
以下示例中,body 標簽下有 h1 和 img 標簽,未添加 filter 樣式前如下所示。
<body><h1>FUTURAMA</h1><img width="500" src="./images/futurama.png" /></body>

現(xiàn)在我們給 body 元素添加一個 .gray 類,<body> 就可實現(xiàn)整個網(wǎng)頁置灰效果。
.gray {filter: grayscale(100%);}

為了兼容 IE8 等其他低版本瀏覽器,我們可以加上瀏覽器前綴和 svg 濾鏡。
.gray {-webkit-filter: grayscale(1);-webkit-filter: grayscale(100%);-moz-filter: grayscale(100%);-ms-filter: grayscale(100%);-o-filter: grayscale(100%);filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#grayscale");filter: progid:DXImageTransform.Microsoft.BasicImage(grayscale=1);filter: grayscale(100%);}
在做緊急置灰網(wǎng)頁需求時,上線一段時間往往需要撤掉這個功能,我們還可以在首次上線時添加以下類似的方法,來控制置灰效果的自動上下線時間,這樣到達預定時間就可自動撤去,不用走兩次施工流程。
(function setGray() {var endTime = Date.parse("Apr 06 2077 00:00:01");var timestamp = Date.parse(new Date());if (timestamp <= endTime) {document.querySelector('html').classList.add('gray');}})();
元素強調(diào)、高亮
brightness 方法實現(xiàn)元素高亮的效果,可以應用到菜單欄、圖片列表 hover 效果,來強調(diào)鼠標當前懸浮或選中的內(nèi)容。
下面是對一組按鈕菜單欄添加 brightness 和 saturate 兩個方法,通過改變亮度和飽和度來高亮元素。
<div><a>1</a><a>1</a><a>1</a></div>
.container {margin: 40px;}.button {padding: 0.5em 0.5em;background: #E0E0E0;border-radius: 3px;}.button.dark {background: #333;}.button:hover:not(.disabled) {cursor: pointer;border-radius: 3px;filter: brightness(110%) saturate(140%);}.button.disabled {filter: grayscale(100%);}
毛玻璃效果
毛玻璃(Frosted glass)效果,顧名思義就是類似半透明毛玻璃的效果,在 iOS 系統(tǒng)、Windows 10 等系統(tǒng) UI 中有廣泛應用,使用毛玻璃效果可以增強視覺體驗。
在 《css揭秘》 等著作中也有系統(tǒng)講解,下面是我對分別使用 filter: blur 和 backdrop-filter: blur兩種方法實現(xiàn)這種效果的總結(jié)。
有兩個含有相同類名 glass 的 div 元素,它們分別被添加兩個類 glass-by-filter 和 glass-by-backdrop-filter 來區(qū)分兩種方法。
<div></div><div></div>
通用樣式,設置毛玻璃元素的大小、圓角等基本樣式:
.glass {height: 300px;width: 300px;border: 1px groove #EFEFEF;border-radius: 12px;background: rgba(242, 242, 242, 0.5);box-shadow: 0 0.3px 0.7px rgba(0, 0, 0, 0.126),0 0.9px 1.7px rgba(0, 0, 0, 0.179), 0 1.8px 3.5px rgba(0, 0, 0, 0.224),0 3.7px 7.3px rgba(0, 0, 0, 0.277), 0 10px 20px rgba(0, 0, 0, 0.4);}
filter: blur 方法,給元素添加了一個 ::before 偽類設置 blur 方法并將其置于底層實現(xiàn)毛玻璃效果。
.glass-by-filter {z-index: 1;box-sizing: border-box;position: relative;}.glass-by-filter::before {content: "";position: absolute;top: 0; right: 0; bottom: 0; left: 0;z-index: -1;background: inherit;filter: blur(10px);}
backdrop-filter: blur 直接在元素上添加 blur 方法實現(xiàn)毛玻璃效果。
.glass-by-backdrop-filter {backdrop-filter: blur(10px);}
實現(xiàn)效果如下圖所示(左:filter、右:backdrop-filter):

【閱讀擴展】毛玻璃邊框效果:https://css-tricks.com/blurred-borders-in-css
藝術(shù)照!甚至可以實現(xiàn)簡易版 insatagram
復古、版畫、油畫、漫畫、液化、老照片、性冷淡、莫蘭迪、賽博朋克、旺達幻視風格通通都可以實現(xiàn)!
通過結(jié)合使用 filter 的所有方法,可以搭配出任意自己想要的效果。
以下是一個簡單的 filter 方法調(diào)節(jié)器,可以調(diào)整每個方法的值,同時實時展示圖片的濾鏡效果。如下圖所示。

頁面主要代碼如下,控制區(qū) #imageEditor 是一個 form 表單,表單每一行分別控制一種filter方法的值,展示區(qū) #imageContainer 內(nèi)部包含一個 img 元素,產(chǎn)生的 filter 濾鏡作用在該元素上。
<form id="imageEditor"><p><label for="gs">Grayscale</label><input id="gs" name="gs" type="range" min="0" max="100" value="0"></p><p><label for="blur">Blur</label><input id="blur" name="blur" type="range" min="0" max="10" value="0"></p><p><label for="br">Exposure</label><input id="br" name="br" type="range" min="0" max="200" value="100"></p><p><label for="ct">Contrast</label><input id="ct" name="ct" type="range" min="0" max="200" value="100"></p><p><label for="huer">Hue Rotate</label><input id="huer" name="huer" type="range" min="0" max="360" value="0"></p><p><label for="opacity">Opacity</label><input id="opacity" name="opacity" type="range" min="0" max="100" value="100"></p><p><label for="invert">Invert</label><input id="invert" name="invert" type="range" min="0" max="100" value="0"></p><p><label for="saturate">Saturate</label><input id="saturate" name="saturate" type="range" min="0" max="500" value="100"></p><p><label for="sepia">Sepia</label><input id="sepia" name="sepia" type="range" min="0" max="100" value="0"></p><input type="reset" form="imageEditor" id="reset" value="Reset" /></form><div id="imageContainer"><img src="futurama.png"></div>
function editImage() {var gs = $("#gs").val(); // grayscalevar blur = $("#blur").val(); // blurvar br = $("#br").val(); // brightnessvar ct = $("#ct").val(); // contrastvar huer = $("#huer").val(); // hue-rotatevar opacity = $("#opacity").val(); // opacityvar invert = $("#invert").val(); // invertvar saturate = $("#saturate").val(); // saturatevar sepia = $("#sepia").val(); // sepia$("#imageContainer img").css("filter", 'grayscale(' + gs+'%) blur(' + blur +'px) brightness(' + br +'%) contrast(' + ct +'%) hue-rotate(' + huer +'deg) opacity(' + opacity +'%) invert(' + invert +'%) saturate(' + saturate +'%) sepia(' + sepia + '%)');$("#imageContainer img").css("-webkit-filter", 'grayscale(' + gs+'%) blur(' + blur +'px) brightness(' + br +'%) contrast(' + ct +'%) hue-rotate(' + huer +'deg) opacity(' + opacity +'%) invert(' + invert +'%) saturate(' + saturate +'%) sepia(' + sepia + '%)');}// 當input值發(fā)生變化時即時應用濾鏡$("input[type=range]").change(editImage).mousemove(editImage);
現(xiàn)在只是實現(xiàn)了濾鏡的實時預覽,后續(xù)待實現(xiàn)功能包括支持復雜的 svg 濾鏡模版、導出下載等,完成這些步驟,以后照片添加濾鏡再也不用下載其他 APP了。實例完整版代碼:https://codepen.io/dragonir/pen/abJmqxM
節(jié)省空間,提高網(wǎng)頁加載速度
實踐證明,同一圖片減小亮度和對比度及色相飽和度之后的體積與原圖相比,可以減小很大一部分體積空間 2M 左右的圖片經(jīng)過弱化后保存,就可以壓縮到 1M 左右。
在網(wǎng)頁中我們可以使用經(jīng)過 弱化 的圖片,然后通過 CSS filter 將其還原。這樣就可以達到壓縮資源體積,提升網(wǎng)頁加載速度、提高用戶體驗的目的。
具體操作可閱讀以下教程:
對比度交換技術(shù):使用 CSS filter 提高圖像性能 https://css-tricks.com/contrast-swap-technique-improved-image-performance-css-filters
兼容性
從 caniuse 查詢結(jié)果可以看出,css filter 屬性在現(xiàn)代瀏覽器中的支持性已經(jīng)很好了,除了 IE 瀏覽器之外,其他瀏覽器中大多可以正常使用,必要時可添加瀏覽器內(nèi)核前綴。
但是官網(wǎng)也有以下3個issue 提示,相信后續(xù)隨著瀏覽器的升級,這些問題也會被逐步修復:
在 Safari 瀏覽器中,如果子元素具有動畫效果,則不會被應用濾鏡。
目前沒有瀏覽器支持 drop-shadow 濾鏡的 spread-radius 方法。
在 Edge 瀏覽器中如果元素或子元素被設置了 負值z-index,則無法應用濾鏡。

總結(jié)
本篇文章只是簡單列舉了幾種使用 CSS filter 常用的頁面效果,其實 filter 的每一種內(nèi)置方法都可以有無限可能的擴展應用,如 invert 反轉(zhuǎn)色同樣也可以應用到 hover 效果上、調(diào)整網(wǎng)頁sepia 褐色值可以實現(xiàn)護眼效果等。
只要發(fā)揮想象力和創(chuàng)造力,filter 都可以在實踐中得到很好的應用。
以下一些例子就是很好的應用,大家有興趣可以拓展閱讀學習:
毛玻璃效果 https://codepen.io/KazuyoshiGoto/pen/nhstF
破碎玻璃效果 https://codepen.io/bajjy/pen/vwrKk
使用filter實現(xiàn)的hover效果 https://codepen.io/nxworld/details/ZYNOBZ
反色按鈕 https://codepen.io/monkey-company/pen/zZZvRp
老照片 https://codepen.io/dudleystorey/pen/pKoqa
高級版filter編輯器:https://codepen.io/stoumann/pen/MWeNmyb
最后附上一張用上面濾鏡編輯器調(diào)出來的 復古莫蘭迪色性冷淡油畫效果 濾鏡圖片。(哇塞,這也太哇塞了吧,CSS 絕絕子 yyds)

學習更多技能
請點擊下方公眾號
![]()

