CSS filter 有哪些神奇用途

背景

基本概念

CSS filter 屬性將模糊或顏色偏移等圖形效果應用於元素造成濾鏡,濾鏡一般用於調整圖像,背景和邊框的渲染。它的值能夠爲 filter 函數 <filter-function> 或使用 url 添加的svg濾鏡。javascript

filter: <filter-function> [<filter-function>]* | none
filter: url(file.svg#filter-element-id)

 <filter-function> 能夠用於 filter 和 backdrop-filter 屬性。它的數據類型由下列過濾器函數之一指定。每一個函數須要一個參數,若是參數無效,則濾鏡不會生效。如下是對濾鏡函數含義的解釋:css

  • blur():模糊圖像
  • brightness() :讓圖像更明亮或更暗淡
  • contrast():增長或減小圖像的對比度
  • drop-shadow():在圖像後方應用投影
  • grayscale():將圖像轉爲灰度圖
  • hue-rotate():改變圖像的總體色調
  • invert():反轉圖像顏色
  • opacity():改變圖像透明度
  • saturate():超飽和或去飽和輸入的圖像
  • sepia():將圖像轉爲棕褐色

用法示例

/* 使用SVG filter */
filter: url("filters.svg#filter-id");
/* 使用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%);
/* 多個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 方法就能很好的解決這個問題,用它添加的陰影能夠穿透元素,而不是添加到元素的盒模型邊框上。html

drop-shadow 添加的陰影除了能夠穿透透明元素外,陰影效果和 box-shadow 是相同的,若是瀏覽器支持硬件加速的話,使用 filter 添加的陰影效果會更加逼真。java

drop-shadow 語法以下(它除了不支持設置 inset,其餘和 box-shadow 是徹底相同的):web

filter: drop-shadow(x偏移, y偏移, 模糊大小, 色值);

如:segmentfault

filter: drop-shadow(1px 1px 15px rgba(0, 0, 0, .5));

下圖是分別使用 box-shadowfilter: drop-shadow 爲透明元素添加陰影的對比:瀏覽器

<img 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));
}

元素、網頁置灰

發生重大災害事故或其餘哀悼日時,國企政府網站每每有網頁所有置灰的需求。或者不少網頁中有鼠標 hover 懸浮到灰色元素上時變成彩色的樣式效果。此時就可使用 filter 屬性的 grayscale 方法實現,它能夠調整元素灰度,經過給頁面元素設置 filter: grayscale(100%) 就可將頁面元素置灰。如下示例中,body 標籤下有 h1img 標籤,未添加 filter 樣式前以下所示。編輯器

<body>
  <h1 class="title">FUTURAMA</h1>
  <img class="img" width="500" src="./images/futurama.png" />
</body>

如今咱們給 body 元素添加一個 .gray 類,<body class="gray"> 就可實現整個網頁置灰效果。svg

.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%);
}

在作緊急置灰網頁需求時,上線一段時間每每須要撤掉這個功能,咱們還能夠在首次上線時添加如下相似的方法,來控制置灰效果的自動上下線時間,這樣到達預約時間就可自動撤去,不用走兩次施工流程。🤣

(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');
  }
})();

元素強調、高亮

brightness 方法實現元素高亮的效果,能夠應用到菜單欄、圖片列表 hover 效果,來強調鼠標當前懸浮或選中的內容。下面是對一組按鈕菜單欄添加 brightnesssaturate 兩個方法,經過改變亮度和飽和度來高亮元素。

<div 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 系統、Windows 10 等系統 UI 中有普遍應用,使用毛玻璃效果能夠加強視覺體驗。在 《CSS揭祕》 等著做中也有系統講解,下面是我對分別使用 filter: blurbackdrop-filter: blur兩種方法實現這種效果的總結。

有兩個含有相同類名 glassdiv 元素,它們分別被添加兩個類 glass-by-filterglass-by-backdrop-filter 來區分兩種方法。

<div class="glass glass-by-filter"></div>
<div class="glass glass-by-backdrop-filter"></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 方法並將其置於底層實現毛玻璃效果。

.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 方法實現毛玻璃效果。

.glass-by-backdrop-filter {
  backdrop-filter: blur(10px);
}

實現效果以下圖所示(左:filter、右:backdrop-filter):

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

藝術照!甚至能夠實現簡易版 insatagram

復古、版畫、油畫、漫畫、液化、老照片、性冷淡、莫蘭迪、賽博朋克、旺達幻視風格統統均可以實現!

經過結合使用 filter 的全部方法,能夠搭配出任意本身想要的效果。如下是一個簡單的 filter 方法調節器,能夠調整每一個方法的值,同時實時展現圖片的濾鏡效果。以下圖所示。

頁面主要代碼以下,控制區 #imageEditor 是一個 form 表單,表單每一行分別控制一種filter方法的值,展現區 #imageContainer 內部包含一個 img 元素,產生的 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" class="center">
  <img src="futurama.png">
</div>
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 + '%)'
  );
}
// 當input值發生變化時即時應用濾鏡
$("input[type=range]").change(editImage).mousemove(editImage);

如今只是實現了濾鏡的實時預覽,後續待實現功能包括支持複雜的 svg 濾鏡模版、導出下載等,完成這些步驟,之後照片添加濾鏡不再用下載其餘 APP😅 了。實例完整版代碼:https://codepen.io/dragonir/p...

節省空間,提升網頁加載速度

實踐證實,同一圖片減少亮度和對比度及色相飽和度以後的體積與原圖相比,能夠減少很大一部分體積空間 2M 左右的圖片通過弱化後保存,就能夠壓縮到 1M 左右。在網頁中咱們可使用通過 弱化 的圖片,而後經過 CSS filter 將其還原。這樣就能夠達到壓縮資源體積,提高網頁加載速度、提升用戶體驗的目的。

具體操做可閱讀如下教程:

對比度交換技術:使用 CSS filter 提升圖像性能 https://css-tricks.com/contra...

兼容性

caniuse 查詢結果能夠看出,css filter 屬性在現代瀏覽器中的支持性已經很好了,除了 IE 瀏覽器以外,其餘瀏覽器中大多能夠正常使用,必要時可添加瀏覽器內核前綴。可是官網也有如下3個issue 提示,相信後續隨着瀏覽器的升級,這些問題也會被逐步修復:

  • 在 Safari 瀏覽器中,若是子元素具備動畫效果,則不會被應用濾鏡。
  • 目前沒有瀏覽器支持 drop-shadow 濾鏡的 spread-radius 方法。
  • Edge 瀏覽器中若是元素或子元素被設置了 負值z-index,則沒法應用濾鏡。

filter_10

總結

本篇文章只是簡單列舉了幾種使用 CSS filter 經常使用的頁面效果,其實 filter 的每一種內置方法均可以有無限可能的擴展應用,如 invert 反轉色一樣也能夠應用到 hover 效果上、調整網頁sepia 褐色值能夠實現護眼效果等。只要發揮想象力和創造力,filter 均可以在實踐中獲得很好的應用。

如下一些例子就是很好的應用,你們有興趣能夠拓展閱讀學習:

最後附上一張用上面濾鏡編輯器調出來的 復古莫蘭迪色性冷淡油畫效果 濾鏡圖片。(哇塞,這也太哇塞了吧,CSS 絕絕子 yyds🤣

filter_9

文章地址: https://segmentfault.com/a/11... 做者:dragonir
相關文章
相關標籤/搜索