奇妙的 CSS MASK

来源:https://www.cnblogs.com/coco1s/archive/2020/07/06/13253423.html
-Advertisement-
Play Games

本文將介紹 CSS 中一個非常有意思的屬性 mask 。 顧名思義,mask 譯為遮罩。在 CSS 中,mask 屬性允許使用者通過遮罩或者裁切特定區域的圖片的方式來隱藏一個元素的部分或者全部可見區域。 其實 mask 的出現已經有一段時間了,只是沒有特別多實用的場景,在實戰中使用的非常少,本文將羅 ...


本文將介紹 CSS 中一個非常有意思的屬性 mask 。

顧名思義,mask 譯為遮罩。在 CSS 中,mask 屬性允許使用者通過遮罩或者裁切特定區域的圖片的方式來隱藏一個元素的部分或者全部可見區域。

其實 mask 的出現已經有一段時間了,只是沒有特別多實用的場景,在實戰中使用的非常少,本文將羅列一些使用 mask 創造出來的有意思的場景。

語法

最基本,使用 mask 的方式是藉助圖片,類似這樣:

{
    /* Image values */
    mask: url(mask.png);                       /* 使用點陣圖來做遮罩 */
    mask: url(masks.svg#star);                 /* 使用 SVG 圖形中的形狀來做遮罩 */
}

當然,使用圖片的方式後文會再講。藉助圖片的方式其實比較繁瑣,因為我們首先還得準備相應的圖片素材,除了圖片,mask 還可以接受一個類似 background 的參數,也就是漸變。

類似如下使用方法:

{
    mask: linear-gradient(#000, transparent)   /* 使用漸變來做遮罩 */
}

那該具體怎麼使用呢?一個非常簡單的例子,上述我們創造了一個從黑色到透明漸變色,我們將它運用到實際中,代碼類似這樣:

下麵這樣一張圖片,疊加上一個從透明到黑色的漸變,

{
    background: url(image.png) ;
    mask: linear-gradient(90deg, transparent, #fff);
}

應用了 mask 之後,就會變成這樣:

這個 DEMO,可以先簡單瞭解到 mask 的基本用法。

這裡得到了使用 mask 最重要結論:圖片與 mask 生成的漸變的 transparent 的重疊部分,將會變得透明。

值得註意的是,上面的漸變使用的是 linear-gradient(90deg, transparent, #fff),這裡的 #fff 純色部分其實換成任意顏色都可以,不影響效果。

CodePen Demo -- 使用 MASK 的基本使用

 

使用 MASK 進行圖片裁切

利用上述簡單的運用,我們可以使用 mask 實現簡單的圖片裁剪。

使用 mask 實現圖片切角遮罩

使用線性漸變,我們實現一個簡單的切角圖形:

.notching{
    width: 200px;
    height: 120px;
    background:
    linear-gradient(135deg, transparent 15px, deeppink 0)
    top left,
    linear-gradient(-135deg, transparent 15px, deeppink 0)
    top right,
    linear-gradient(-45deg, transparent 15px, deeppink 0)
    bottom right,
    linear-gradient(45deg, transparent 15px, deeppink 0)
    bottom left;
    background-size: 50% 50%;
    background-repeat: no-repeat;
}

像是這樣:

我們將上述漸變運用到 mask 之上,而 background 替換成一張圖片,就可以得到運用了切角效果的圖片:

    background: url(image.png);
    mask:
        linear-gradient(135deg, transparent 15px, #fff 0)
        top left,
        linear-gradient(-135deg, transparent 15px, #fff 0)
        top right,
        linear-gradient(-45deg, transparent 15px, #fff 0)
        bottom right,
        linear-gradient(45deg, transparent 15px, #fff 0)
        bottom left;
    mask-size: 50% 50%;
    mask-repeat: no-repeat;

得到的效果如下:

CodePen Demo -- 使用 MASK 實現圖片切角遮罩

當然,實現上述效果還有其他很多種方式,譬如 clip-path,這裡的 mask 也是一種方式。

 

多張圖片下使用 mask

上述是單張圖片使用 mask 的效果。下麵我們看看多張圖片下,使用 mask 能碰撞出什麼樣的火花。

假設我們有兩張圖片,使用 mask,可以很好將他們疊加在一起進行展示。最常見的一個用法:

div {
    position: relative;
    background: url(image1.jpg);

    &::before {
        position: absolute;
        content: "";
        top: 0;left: 0; right: 0;bottom: 0;
        background: url(image2.jpg);
        mask: linear-gradient(45deg, #000 50%, transparent 50%);
    }
}

兩張圖片,一張完全重疊在另外一張之上,然後使用 mask: linear-gradient(45deg, #000 50%, transparent 50%) 分割兩張圖片:

CodePen Demo -- MASK 的基本使用,多張圖片下的基本用法

當然,註意上面我們使用的 mask 的漸變,是完全的實色變化,沒有過度效果。

我們稍微修改一下 mask 內的漸變:

{
- mask: linear-gradient(45deg, #000 50%, transparent 50%)
+ mask: linear-gradient(45deg, #000 40%, transparent 60%)
}

即可得到圖片1向圖片2過渡切換的效果:

CodePen Demo -- MASK 的基本使用,多張圖片下的基本用法2

 

使用 MASK 進行轉場動畫

有了上面的鋪墊。運用上面的介紹的一些方法,我們就可以使用 mask 來進行一些圖片切換間的轉場動畫。

 

使用線性漸變 mask:linear-gradient() 進行切換

還是上面的 Demo,我們通過動態的去改變 mask 的值來實現圖片的顯示/轉場效果。

代碼可能是這樣:

div {
    background: url(image1.jpg);
    animation: maskMove 2s linear;
}
@keyframes {
  0% {
    mask: linear-gradient(45deg, #000 0%, transparent 5%, transparent 5%);
  }
  1% {
    mask: linear-gradient(45deg, #000 1%, transparent 6%, transparent 6%);
  }
  ...
  100% {
    mask: linear-gradient(45deg, #000 100%, transparent 105%, transparent 105%);
  }
}

當然,像上面那樣一個一個寫,會比較費力,通常我們會藉助 SASS/LESS 等預處理器進行操作。像是這樣:

div {
    position: relative;
    background: url(image2.jpg) no-repeat;

    &::before {
        position: absolute;
        content: "";
        top: 0;left: 0; right: 0;bottom: 0;
        background: url(image1.jpg);
        animation: maskRotate 1.2s ease-in-out;
    }
}

@keyframes maskRotate {
    @for $i from 0 through 100 { 
        #{$i}% {
            mask: linear-gradient(45deg, #000 #{$i + '%'}, transparent #{$i + 5 + '%'}, transparent 1%);
        }
    }
}

可以得到下麵這樣的效果(單張圖片的顯隱及兩張圖片下的切換):


CodePen Demo -- MASK linear-gradient 轉場

 

使用角向漸變 mask: conic-gradient() 進行切換

當然,除了 mask: linear-gradient(),使用徑向漸變或者角向漸變也都是可以的。使用角向漸變的原理也是一樣的:

@keyframes maskRotate {
    @for $i from 0 through 100 { 
        #{$i}% {
            mask: conic-gradient(#000 #{$i - 10 + '%'}, transparent #{$i + '%'}, transparent);
        }
    }
}

可以實現圖片的角向漸顯/切換:

CodePen Demo -- MASK conic-gradient 轉場

這個技巧,在張鑫旭的這篇文章里,有更多豐富的例子,可以移步閱讀:

你用的那些CSS轉場動畫可以換一換了

運用這個技巧,我們就可以實現很多有意思的圖片效果。像是這樣:

mask4

 

mask 碰撞濾鏡與混合模式

繼續下一環節。CSS 中很多有意思的屬性,和濾鏡和混合模式一結合,會碰撞出更多火花。

 

mask & 濾鏡 filter: contrast()

首先,我們利用多重徑向漸變,實現這樣一張圖。

{
  background: radial-gradient(#000, transparent);
  background-size: 20px 20px;
}

看著沒什麼特別,我們利用 filter: contrast() 對比度濾鏡,改造一下。代碼大概是這樣:

html,body {
    width: 100%;
    height: 100%;
    filter: contrast(5);
}

div {
    position: relative;
    width: 100%;
    height: 100%;
    background: #fff;
    
    &::before {
        content: "";
        position: absolute;
        top: 0; right: 0; bottom: 0; left: 0;
        background: radial-gradient(#000, transparent);
        background-size: 20px 20px;
    }
} 

即可得到這樣的圖形,利用對比度濾鏡,將圖形變得非常的銳化。

這個時候,我們再疊加上不同的 mask 遮罩。即可得到各種有意思的圖形效果。

body {
    filter: contrast(5);
}

div {
    position: relative;
    background: #fff;
    
    &::before {
        background: radial-gradient(#000, transparent);
        background-size: 20px 20px;
      + mask: linear-gradient(-180deg, rgba(255, 255, 255, 1), rgba(255, 255, 255, .5));
    }
}

CodePen Demo -- 使用 mask 搭配濾鏡 contrast

我們疊加了一個線性漸變的 mask linear-gradient(-180deg, rgba(255, 255, 255, 1), rgba(255, 255, 255, .5)),註意,兩個漸變顏色都是帶透明度的。

或者換一個徑向漸變:

{
    mask: repeating-radial-gradient(circle at 35% 65%, #000, rgba(0, 0, 0, .5), #000 25%);
}

CodePen Demo -- 使用 mask 搭配濾鏡 contrast

好的,下一步,與上文類似,我們添加上動畫。

div {
    ...
    
    &::before {
        background: radial-gradient(#000, transparent);
        background-size: 20px 20px;
        mask: repeating-radial-gradient(circle at 35% 65%, #000, rgba(0, 0, 0, .5), #000 25%);
        animation: maskMove 15s infinite linear;
    }
}

@keyframes maskMove {
    @for $i from 0 through 100 { 
        #{$i}% {
            mask: repeating-radial-gradient(circle at 35% 65%, #000, rgba(0, 0, 0, .5), #000 #{$i + 10 +  '%'});
        }
    }
}

看看,可以得到了非常酷炫的動畫效果:

CodePen Demo -- 使用 mask 搭配濾鏡 contrast 及動畫

還記得使用 filter: hue-rotate() 色相濾鏡嗎。再加上它,我們可以讓顏色也變化起來。

CodePen Demo -- 使用 mask 搭配濾鏡 contrast 及動畫2

 

mask & 濾鏡 filter: contrast() & 混合模式

接下來我們再疊加上混合模式。

註意到上面,其實我們的容器背景色是白色 #fff

我們可以通過多嵌套一層層級,再增加一個容器背景色,再疊加上混合模式,產生不一樣的效果。

先不添加使用 mask,重新構造一下結構,最終的偽代碼帶個是這樣:

<div class="wrap">
    <div class="inner"></div>
</div>
.wrap {
    position: relative;
    height: 100%;
    background: linear-gradient(45deg, #f44336, #ff9800, #ffeb3b, #8bc34a, #00bcd4, #673ab7);
}

.inner {
    height: 100%;
    background: #000;
    filter: contrast(700%);
    mix-blend-mode: multiply;
    
    &::before {
        content: "";
        position: absolute;
        top: 0; right: 0; bottom: 0; left: 0;
        background: radial-gradient(#fff, transparent);
        background-size: 12px 12px;
    }
}

原理示例圖如下:

我們就可以得到如下的效果:

OK,到這一步,mask 還沒有運用上,我們再添加上 mask。

.wrap {
    background: linear-gradient(45deg, #f44336, #ff9800, #ffeb3b, #8bc34a, #00bcd4, #673ab7);
}

.inner {
    ...
    filter: contrast(700%);
    mix-blend-mode: multiply;
    
    &::before {
        background: radial-gradient(#fff, transparent);
        background-size: 12px 12px;
      + mask: linear-gradient(#000, rgba(0, 0, 0, .5));
    }
}

CodePen Demo -- mask & filter & blend-mode

實際效果比截圖好很多,可以點擊 Demo 去看看。

當然,這裡疊加的是 mix-blend-mode: multiply ,可以嘗試其他混合模式,得到其他不一樣的效果。

譬如,疊加 mix-blend-mode: difference,等等等等:

更多有意思的疊加,感興趣的同學需要自己多加嘗試。

 

mask 與圖片

當然,mask 最本質的作用應該還是作用於圖片。上面得到的重要結論:

圖片與 mask 生成的漸變的 transparent 的重疊部分,將會變得透明。

也可以作用於 mask 屬性傳入的圖片。也就是說,mask 是可以傳入圖片素材的,並且遵循 background-image 與 mask 圖片的透明重疊部分,將會變得透明。

運用這個技巧,可以製作非常酷炫的轉場動畫:

這裡其實主要是在 mask 中運用了這樣一張圖片:

然後,使用了逐幀動畫,快速切換每一幀的 mask :

.img1 {
    background: url(image1.jpg) no-repeat left top;
}

.img2 {
    mask: url(https://i.imgur.com/AYJuRke.png);
    mask-size: 3000% 100%;
    animation: maskMove 2s steps(29) infinite;
}

.img2::before {
    background: url(image2.jpg) no-repeat left top;
}

@keyframes maskMove {
    from {
        mask-position: 0 0;
    }
    to {
        mask-position: 100% 0;
    }
}

CodePen Demo -- mask 製作轉場動畫

當然,這個也是可以加上各種動畫的。上面已經演示了很多次了,感興趣的同學可以自己嘗試嘗試。

 

最後

說了這麼多,mask 其實還是屬於一個比較冷門的屬性。在日常業務中能運用上的機會不多。

而且相容性不算特別好,打開 MDN,可以看到,除了 mask 本身,還有很多與 mask 相關的屬性,只是目前大部分還屬於實驗室階段。本文只是初略的介紹了 mask 本身,對 mask 相關的一些屬性將會另起一文。

當然,即便如此,從屬性本身而言,我覺得 mask 還是非常有意思的,帶來了 CSS 更多可能性。


好了,本文到此結束,希望對你有幫助 :)

更多精彩 CSS 技術文章彙總在我的 Github -- iCSS ,持續更新,歡迎點個 star 訂閱收藏。

如果還有什麼疑問或者建議,可以多多交流,原創文章,文筆有限,才疏學淺,文中若有不正之處,萬望告知。

 

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • <script type="text/javascript"> function clickIE4() { if (event.button == 2) { return false; } } function clickNS4(e) { if (document.layers || documen ...
  • 最近在教我老婆學習前端,她說想要學習前端,自己在家賺點外快,自己賺點家用。我也拗不過她,而且其實我也挺佩服的。所以就教她了。最近我想考一考她對css中偽類的瞭解,所以就問了她瞭解css多少個偽類,偽類是什麼? 她說css 偽類是用於向某些選擇器添加特殊的效果,是動態的,指當前元素所處的狀態或者特性。 ...
  • 直接複製就能用 wxml <view bindtap="showModal">點這裡</view> <view class="wrap"> <view class="modal modal-bottom-dialog" hidden="{{hideFlag}}"> <view class="moda ...
  • 前言 前幾天,我接到了一個項目,模塊中要寫一個卡券效果,當時沒有圖片,也就是要用css來實現,當時我是懵逼的,也沒有寫過這樣的,一時間不知道怎麼寫,畢竟要寫的像UI設計的一樣美觀。我就只好求救我的大神級別的同事了。不僅css玩的溜,人家JavaScript玩的更溜,閣下實在是佩服。 常見的卡券樣式如 ...
  • 題目 function Foo() { getName = function () { alert (1); }; return this; } Foo.getName = function () { alert (2);}; Foo.prototype.getName = function ()  ...
  • 具體開發中遇到的問題如下, 數據表格內的 內容 通過 table.cache["SampleList"] 修改後,重新渲染或重新載入會導致當前操作的分頁 和 配置被清空。我修改了第5頁第X行的X列值,重新渲染後就回到了最原始第1頁或重新調用了介面。 Layui 官方提供的文檔 提供的刷新表格方法有幾 ...
  • 今天看見徒弟寫個css屬性這麼慢,是在是看不下去了,就問了他有沒有用過一些輔助工具,他說沒有,額。。。我也是很無語,沒辦法,誰叫我是他師傅呢。還是要盡到一個師傅的責任。所以就利用休息時間給他講了19個輔助工具,滿滿的乾貨呀。我這也是第一次給別人說這麼多,這麼詳細,想想還不錯,教給別人東西的感覺是不一 ...
  • 2020年是充滿機遇與挑戰的一年,這一年註定不平凡。隨著5G商用、傳統產業數字化轉型加快,我們完全可以想象到互聯網行業即將迎來自己的“高光時刻”,因此,現在學習web前端正當時。 那麼,對於零基礎小白而言,如何才能快速學習web前端呢?下麵,就為大家分享2020年web前端學習路線。 很多對於web ...
一周排行
    -Advertisement-
    Play Games
  • GoF之工廠模式 @目錄GoF之工廠模式每博一文案1. 簡單說明“23種設計模式”1.2 介紹工廠模式的三種形態1.3 簡單工廠模式(靜態工廠模式)1.3.1 簡單工廠模式的優缺點:1.4 工廠方法模式1.4.1 工廠方法模式的優缺點:1.5 抽象工廠模式1.6 抽象工廠模式的優缺點:2. 總結:3 ...
  • 新改進提供的Taurus Rpc 功能,可以簡化微服務間的調用,同時可以不用再手動輸出模塊名稱,或調用路徑,包括負載均衡,這一切,由框架實現並提供了。新的Taurus Rpc 功能,將使得服務間的調用,更加輕鬆、簡約、高效。 ...
  • 本章將和大家分享ES的數據同步方案和ES集群相關知識。廢話不多說,下麵我們直接進入主題。 一、ES數據同步 1、數據同步問題 Elasticsearch中的酒店數據來自於mysql資料庫,因此mysql數據發生改變時,Elasticsearch也必須跟著改變,這個就是Elasticsearch與my ...
  • 引言 在我們之前的文章中介紹過使用Bogus生成模擬測試數據,今天來講解一下功能更加強大自動生成測試數據的工具的庫"AutoFixture"。 什麼是AutoFixture? AutoFixture 是一個針對 .NET 的開源庫,旨在最大程度地減少單元測試中的“安排(Arrange)”階段,以提高 ...
  • 經過前面幾個部分學習,相信學過的同學已經能夠掌握 .NET Emit 這種中間語言,並能使得它來編寫一些應用,以提高程式的性能。隨著 IL 指令篇的結束,本系列也已經接近尾聲,在這接近結束的最後,會提供幾個可供直接使用的示例,以供大伙分析或使用在項目中。 ...
  • 當從不同來源導入Excel數據時,可能存在重覆的記錄。為了確保數據的準確性,通常需要刪除這些重覆的行。手動查找並刪除可能會非常耗費時間,而通過編程腳本則可以實現在短時間內處理大量數據。本文將提供一個使用C# 快速查找並刪除Excel重覆項的免費解決方案。 以下是實現步驟: 1. 首先安裝免費.NET ...
  • C++ 異常處理 C++ 異常處理機制允許程式在運行時處理錯誤或意外情況。它提供了捕獲和處理錯誤的一種結構化方式,使程式更加健壯和可靠。 異常處理的基本概念: 異常: 程式在運行時發生的錯誤或意外情況。 拋出異常: 使用 throw 關鍵字將異常傳遞給調用堆棧。 捕獲異常: 使用 try-catch ...
  • 優秀且經驗豐富的Java開發人員的特征之一是對API的廣泛瞭解,包括JDK和第三方庫。 我花了很多時間來學習API,尤其是在閱讀了Effective Java 3rd Edition之後 ,Joshua Bloch建議在Java 3rd Edition中使用現有的API進行開發,而不是為常見的東西編 ...
  • 框架 · 使用laravel框架,原因:tp的框架路由和orm沒有laravel好用 · 使用強制路由,方便介面多時,分多版本,分文件夾等操作 介面 · 介面開發註意欄位類型,欄位是int,查詢成功失敗都要返回int(對接java等強類型語言方便) · 查詢介面用GET、其他用POST 代碼 · 所 ...
  • 正文 下午找企業的人去鎮上做貸後。 車上聽同事跟那個司機對罵,火星子都快出來了。司機跟那同事更熟一些,連我在內一共就三個人,同事那一手指桑罵槐給我都聽愣了。司機也是老社會人了,馬上聽出來了,為那個無辜的企業經辦人辯護,實際上是為自己辯護。 “這個事情你不能怪企業。”“但他們總不能讓銀行的人全權負責, ...