【CSS】1149- CSS filter 有哪些神奇用途

背景
基本概念
CSS filter?屬性將模糊或顏色偏移等圖形效果應(yīng)用于元素形成濾鏡,濾鏡通常用于調(diào)整圖像,背景和邊框的渲染。它的值可以為 filter 函數(shù) 或使用 url 添加的svg濾鏡。
filter:??[]*?|?none
filter:?url(file.svg#filter-element-id)
?可以用于 filter?和?backdrop-filter?屬性。它的數(shù)據(jù)類型由下列過(guò)濾器函數(shù)之一指定。每個(gè)函數(shù)需要一個(gè)參數(shù),如果參數(shù)無(wú)效,則濾鏡不會(huì)生效。以下是對(duì)濾鏡函數(shù)含義的解釋:
blur():模糊圖像brightness():讓圖像更明亮或更暗淡contrast():增加或減少圖像的對(duì)比度drop-shadow():在圖像后方應(yīng)用投影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%);
/*?多個(gè)filter?*/
filter:?contrast(175%)?brightness(3%);
/*?不使用filter?*/
filter:?none;
/*?全局變量?*/
filter:?inherit;
filter:?initial;
filter:?unset;

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

class="box-shadow"?src="futurama.png"?/>
<img?class="drop-shadow"?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)頁(yè)置灰
發(fā)生重大災(zāi)害事故或其他哀悼日時(shí),國(guó)企政府網(wǎng)站往往有網(wǎng)頁(yè)全部置灰的需求?;蛘吆芏嗑W(wǎng)頁(yè)中有鼠標(biāo) hover 懸浮到灰色元素上時(shí)變成彩色的樣式效果。此時(shí)就可以使用 filter 屬性的 grayscale 方法實(shí)現(xiàn),它可以調(diào)整元素灰度,通過(guò)給頁(yè)面元素設(shè)置 filter: grayscale(100%) 就可將頁(yè)面元素置灰。以下示例中,body 標(biāo)簽下有 h1 和 img 標(biāo)簽,未添加 filter 樣式前如下所示。
??<h1?class="title">FUTURAMAh1>
??<img?class="img"?width="500"?src="./images/futurama.png"?/>
</body>

現(xiàn)在我們給 body 元素添加一個(gè) .gray 類, 就可實(shí)現(xiàn)整個(gè)網(wǎng)頁(yè)置灰效果。
.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,#grayscale");
??filter:?progid:DXImageTransform.Microsoft.BasicImage(grayscale=1);
??filter:?grayscale(100%);
}
在做緊急置灰網(wǎng)頁(yè)需求時(shí),上線一段時(shí)間往往需要撤掉這個(gè)功能,我們還可以在首次上線時(shí)添加以下類似的方法,來(lái)控制置灰效果的自動(dòng)上下線時(shí)間,這樣到達(dá)預(yù)定時(shí)間就可自動(dò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');
??}
})();
元素強(qiáng)調(diào)、高亮
brightness 方法實(shí)現(xiàn)元素高亮的效果,可以應(yīng)用到菜單欄、圖片列表 hover 效果,來(lái)強(qiáng)調(diào)鼠標(biāo)當(dāng)前懸浮或選中的內(nèi)容。下面是對(duì)一組按鈕菜單欄添加 brightness 和 saturate 兩個(gè)方法,通過(guò)改變亮度和飽和度來(lái)高亮元素。

class="container">
??<a?class="button">??a>
??<a?class="button">??a>
??<a?class="button">??a>
??<a?class="button?dark">??a>
??<a?class="button?dark">??a>
??<a?class="button?dark">??a>
??<a?class="button?disabled">??a>
??<a?class="button?disabled">??a>
??<a?class="button?disabled">??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 中有廣泛應(yīng)用,使用毛玻璃效果可以增強(qiáng)視覺(jué)體驗(yàn)。在 《CSS揭秘》 等著作中也有系統(tǒng)講解,下面是我對(duì)分別使用 filter: blur 和 backdrop-filter: blur兩種方法實(shí)現(xiàn)這種效果的總結(jié)。
有兩個(gè)含有相同類名 glass 的 div 元素,它們分別被添加兩個(gè)類 glass-by-filter 和 glass-by-backdrop-filter 來(lái)區(qū)分兩種方法。
class="glass?glass-by-filter"></div>
div>
通用樣式,設(shè)置毛玻璃元素的大小、圓角等基本樣式:
.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 方法,給元素添加了一個(gè) ::before 偽類設(shè)置 blur 方法并將其置于底層實(shí)現(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 方法實(shí)現(xiàn)毛玻璃效果。
.glass-by-backdrop-filter?{
??backdrop-filter:?blur(10px);
}
實(shí)現(xiàn)效果如下圖所示(左:filter、右:backdrop-filter):

閱讀擴(kuò)展:毛玻璃邊框效果:https://css-tricks.com/blurre...

藝術(shù)照!甚至可以實(shí)現(xiàn)簡(jiǎn)易版 insatagram
復(fù)古、版畫、油畫、漫畫、液化、老照片、性冷淡、莫蘭迪、賽博朋克、旺達(dá)幻視風(fēng)格通通都可以實(shí)現(xiàn)!
通過(guò)結(jié)合使用 filter 的所有方法,可以搭配出任意自己想要的效果。以下是一個(gè)簡(jiǎn)單的 filter 方法調(diào)節(jié)器,可以調(diào)整每個(gè)方法的值,同時(shí)實(shí)時(shí)展示圖片的濾鏡效果。如下圖所示。

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

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

filter_9 關(guān)于本文
https://segmentfault.com/a/1190000040058430
作者:dragonir

1. JavaScript 重溫系列(22篇全)
2. ECMAScript 重溫系列(10篇全)
3. JavaScript設(shè)計(jì)模式 重溫系列(9篇全) 4.?正則 / 框架 / 算法等 重溫系列(16篇全) 5.?Webpack4 入門(上)||?Webpack4 入門(下) 6.?MobX 入門(上)?||??MobX 入門(下) 7. 120+篇原創(chuàng)系列匯總 回復(fù)“加群”與大佬們一起交流學(xué)習(xí)~
點(diǎn)擊“閱讀原文”查看 130+ 篇原創(chuàng)文章
瀏覽
21
