css: mask淺析

前言

承接上一篇,趁熱打鐵,這篇來聊聊css遮罩相關的屬性,css遮罩相關的屬性以前本身也用的很少,可是在實際使用以後,真的強大好用,準備了這篇文章,總結分享給你們,話很少說,進入正文css

mask相關屬性

css mask屬性在使用時相似backgroud屬性,是多個屬性合在一塊兒的簡寫,具體請看:html

  • mask-image
  • mask-mode
  • mask-repeat
  • mask-position
  • mask-clip
  • mask-origin
  • mask-size
  • mask-composite

接下來就逐一來看每一個屬性的做用web

mask-image

mask-image屬性指的是做用於元素上的遮罩層圖像,mask-image屬性十分強大,支持的功能符不少,雖然有一部分函數並非全部瀏覽器都支持,但並不影響它的強大做用,一看就知道是mask的主力,接下來就經過一些例子來看看mask-image都支持哪些功能符吧,下面例子中全部的原圖都是:
瀏覽器

url()

url功能符是mask-image支持的最基本功能符,能夠經過url()使用一張圖片做爲遮罩,舉個例子:dom

<div class="wrap">
  <img class="lake" src="../img/lake.jpg">
</div>
.wrap {
  display: inline-block;
  line-height: 1;
}
.lake {
  width: 300px;
  mask-image: url('../img/circle.png');
  -webkit-mask-image: url('../img/circle.png');
  mask-repeat: no-repeat;
  -webkit-mask-repeat: no-repeat;
}

上面例子中使用了一個圓形做爲遮罩:

最後的遮罩效果:

原圖是一個長方形的圖片,經過一個圓形的遮罩圖片將長方形的圖片變成一個圓形的圖片,這是比較經常使用的遮罩效果,url功能不只支持常規的圖片地址做爲遮罩,還支持將SVG做爲遮罩,舉個例子:svg

<img class="lake" src="../img/lake.jpg">
<svg>
  <defs>
    <mask id="mask">
        <path fill="white" d="M 10,30
        A 20,20 0,0,1 50,30
        A 20,20 0,0,1 90,30
        Q 90,60 50,90
        Q 10,60 10,30 z">
        </path>
    </mask>
  </defs>
</svg>
.lake {
  width: 300px;
  mask: url(#mask);
  mask-image: url(#mask);
  -webkit-mask-image: url(#mask);
}

最終效果以下圖:

可是有點遺憾,這是在Firefox瀏覽器上的顯示效果,在Chrome瀏覽器並顯示一片空白,SVG的這種寫法在Chrome上不支持,那有什麼辦法能在兩邊都支持呢?將image內聯在SVG中,舉個例子:函數

<svg width="0" height="0">
  <defs>
      <mask id="mask">
        <path fill="white" d="M 10,30
        A 20,20 0,0,1 50,30
        A 20,20 0,0,1 90,30
        Q 90,60 50,90
        Q 10,60 10,30 z">
        </path>
      </mask>
  </defs>
</svg>
<svg width="300" height="200">
  <image class="lake" xlink:href="../img/lake.jpg"></image>
</svg>
.lake {
  width: 300px;
  mask: url(#mask);
  mask-image: url(#mask);
  -webkit-mask-image: url(#mask);
}

和上一個例子惟一的不一樣就是這裏將image內聯在一個svg標籤中了,而不是一個單獨的圖片標籤,這樣就能同時在Chrome和Firefox上顯示,佈局

這裏之因此能在Chrome上顯示還有一個緣由就是mask: url(#mask),在Chrome上生效的實際上是這個屬性

image()

image功能符支持兩個參數,第一個url()圖片連接,第二個color顏色,舉個例子:flex

<div class="wrap">
  <img class="lake" src="../img/lake.jpg">
</div>
.wrap {
  display: inline-block;
  line-height: 1;
}
.lake {
  width: 300px;
  mask-image: image(url('../img/circle.png'), skyblue);
  -webkit-mask-image: image(url('../img/circle.png'), skyblue);
  mask-repeat: no-repeat;
  -webkit-mask-repeat: no-repeat;
}

惋惜的是上面例子在Chrome和Firefox上都不支持,看不到具體的遮罩效果url

image-set

image-set功能符支持兩個參數,第一個是url()遮罩的連接,第二個是設備像素密度,能夠經過不一樣的屏幕密度設置不一樣的的遮罩,舉個例子:

<div class="wrap">
  <img class="lake" src="../img/lake.jpg">
</div>
.lake {
  width: 300px;
  mask-image: image-set(url(../img/circle.png) 1x, url(../img/circle.png) 2x);
  -webkit-mask-image: -webkit-image-set(url(../img/circle.png) 1x, url(../img/heart1.png) 2x);
  mask-repeat: no-repeat;
  -webkit-mask-repeat: no-repeat;
}



在上面例子中,當設備像素比爲1時,設置的是一張圓形的遮罩圖,當設備像素比爲2或者比2大時設置的是一張心形的遮罩圖,不過遺憾的是,在Firefox上不支持,沒法看到效果

element()

element功能符支持將一個dom節點做爲遮罩,參數是dom節點的id,舉個例子:

<div class="wrap">
  <img id="mask" src="../img/circle.png">
  <img class="lake" src="../img/lake.jpg">
</div>
.lake {
  width: 300px;
  mask-image: element(#mask);
  mask-image: -moz-element(#mask);
  -webkit-mask-image: element(#mask);
  mask-repeat: no-repeat;
  -webkit-mask-repeat: no-repeat;
}
#mask {
  width: 0;
  height: 0;
}


上面例子中遮罩設置爲一個img元素的id,也能實現一樣的效果,可是在Chrome瀏覽器上沒有效果,在Firefox上是沒問題的

cross-fade()

cross-fade功能符用於在必定透明度下混合兩張圖片遮罩,舉個例子:

<div class="wrap">
  <img class="lake" src="../img/lake.jpg">
</div>
.lake {
  width: 300px;
  mask-image: cross-fade(url(../img/circle.png), url('../img/favor_fill.svg'), 90%);
  -webkit-mask-image: -webkit-cross-fade(url(../img/circle.png), url('../img/favor_fill.svg'), 90%);
  mask-repeat: no-repeat;
  -webkit-mask-repeat: no-repeat;
}


上面例子中設置兩張圖片遮罩,一張是圓形的遮罩圖,一張是五角星形的svg遮罩,90%設置的是第二張五角星遮罩的透明度,第一張圓形遮罩的透明度就是10%,可是這個功能符在Firefox上不支持

gradient

gradient應該你們都很熟悉,能夠取值linear-gradient(), radial-gradient(), repeating-linear-gradient(), repeating-radial-gradient(),若是對漸變的語法不熟悉,能夠上MDN去看具體的用法,這裏就只介紹漸變做爲遮罩的效果,舉個例子:

<div class="wrap">
  <img class="lake" src="../img/lake.jpg">
</div>
.lake {
  width: 300px;
  mask-image: repeating-radial-gradient(#000, #000 5px, transparent 5px, transparent 10px);
  -webkit-mask-image: repeating-radial-gradient(#000, #000 5px, transparent 5px, transparent 10px);
}


上面例子使用了重複徑向做爲遮罩,漸變遮罩在Chrome和Firefox上是都支持的,mask-image相關的用法到這裏就算是介紹完了,接下來就來看看其餘屬性的用法

mask-mode

mask-mode屬性有三個取值:

  • match-source: mask-mode默認取值,當mask-image的值是一個svg資源時,mask-mode取luminance,其他都取alpha
  • alpha: 基於透明度的遮罩
  • luminance: 基於亮度的遮罩

分別都是什麼效果呢?來看個例子:

遮罩圖

<div class="wrap">
  <img class="lake" src="../img/lake.jpg">
</div>
.lake {
  width: 300px;
  mask-image: url('../img/star1.png');
  -webkit-mask-image: url('../img/star1.png');
  mask-mode: luminance;
  -webkit-mask-mode: luminance;
}
.lake {
  width: 300px;
  mask-image: url('../img/star1.png');
  -webkit-mask-image: url('../img/star1.png');
  mask-mode: luminance;
  -webkit-mask-mode: luminance;
}

.lake {
  width: 300px;
  mask-image: url('../img/star1.png');
  -webkit-mask-image: url('../img/star1.png');
  mask-mode: alpha;
  -webkit-mask-mode: alpha;
}


從上面例子中能夠看到明顯基於alpha的遮罩要比基於luminance的遮罩顏色要深,這個屬性在Chrome上是不支持的,可是Firefox可用

mask-repeat

mask-repeat定義了遮罩是否重複以及如何重複,取值以下:

  • repeat: 默認值,遮罩會在圖片區域重複繪製
  • space: 遮罩儘量多的平鋪,且遮罩之間產生間距,遮罩圖片不會被裁剪
  • round: 遮罩會壓縮或者拉伸佔滿整個圖片
  • no-repeat: 遮罩不會重複

下面來看具體例子:

.lake {
  width: 300px;
  mask-image: url('../img/heart1.png');
  -webkit-mask-image: url('../img/heart1.png');
  mask-repeat: repeat;
  -webkit-mask-repeat: repeat;
}


repeat-x:

repeat-y:

space:

round:

no-repeat:

mask-position

定義遮罩圖片的位置,取值:top|bottom|left|right|center|percentage
舉個例子:

.lake {
  width: 400px;
  mask-image: url('../img/circle.png');
  -webkit-mask-image: url('../img/circle.png');
  mask-repeat: no-repeat;
  -webkit-mask-repeat: no-repeat;
  mask-position: top center;
  -webkit-mask-position: top center;
}

mask-clip

mask-clip定義了mask-image做用的圖片區域,mask-image只會繪製在指定區域內,取值:content-box|padding-box|border-box|margin-box|fill-box|stroke-box|view-box|no-clip,取值看起來不少,可是實際上有效果的就幾個,接下來就來看看具體的每一個取值的效果:

.lake {
  width: 300px;
  mask-image: url('../img/star1.png');
  -webkit-mask-image: url('../img/star1.png');
  margin: 20px;
  padding: 15px;
  border: 10px solid #000; 
}

原圖,沒有加mask-clip的時候

.lake {
  width: 300px;
  mask-image: url('../img/star1.png');
  -webkit-mask-image: url('../img/star1.png');
  margin: 20px;
  padding: 15px;
  border: 10px solid #000; 
  mask-clip: content-box;
  -webkit-mask-clip: content-box;
}
.lake {
  width: 300px;
  mask-image: url('../img/star1.png');
  -webkit-mask-image: url('../img/star1.png');
  margin: 20px;
  padding: 15px;
  border: 10px solid #000; 
  mask-clip: padding-box;
  -webkit-mask-clip: padding-box;
}


因爲圖片的padding部分是不顯示遮罩圖片的,所以content-box和padding-box的遮罩效果相同

.lake {
  width: 300px;
  mask-image: url('../img/star1.png');
  -webkit-mask-image: url('../img/star1.png');
  margin: 20px;
  padding: 15px;
  border: 10px solid #000; 
  mask-clip: border-box;
  -webkit-mask-clip: border-box;
}


margin-box、fill-box、stroke-box、view-box、no-clip這幾個屬性,很遺憾在Chrome和Firefox上嘗試了一下都沒用

mask-origin

mask-origin指定了mask-image遮罩圖片繪製的初始位置,取值:content-box|padding-box|border-box|margin-box|fill-box|stroke-box|view-box,接下來就來看每一個取值的具體效果:

.lake {
  width: 300px;
  mask-image: url('../img/heart1.png');
  -webkit-mask-image: url('../img/heart1.png');
  margin: 20px;
  padding: 15px;
  border: 10px solid #000; 
  mask-origin: content-box;
  -webkit-mask-origin: content-box;
  mask-repeat: no-repeat;
  -webkit-mask-repeat: no-repeat;
}


整個遮罩的初始位置以content-box爲起點

.lake {
  width: 300px;
  mask-image: url('../img/heart1.png');
  -webkit-mask-image: url('../img/heart1.png');
  margin: 20px;
  padding: 15px;
  border: 10px solid #000; 
  mask-origin: padding-box;
  -webkit-mask-origin: padding-box;
  mask-repeat: no-repeat;
  -webkit-mask-repeat: no-repeat;
}


整個遮罩的初始位置以padding-box爲起點,所以遮罩的一部分被paading遮掉了

.lake {
  width: 300px;
  mask-image: url('../img/heart1.png');
  -webkit-mask-image: url('../img/heart1.png');
  margin: 20px;
  padding: 15px;
  border: 10px solid #000; 
  mask-origin: border-box;
  -webkit-mask-origin: border-box;
  mask-repeat: no-repeat;
  -webkit-mask-repeat: no-repeat;
}


整個遮罩的初始位置以border-box爲起點,padding部分依舊是被遮掉了。
和mask-clip同樣,margin-box、fill-box、stroke-box、view-box這幾個屬性在Chrome和Firefox瀏覽器沒有用

mask-size

mask-size指定了mask-image遮罩的大小,取值:contain|cover|length|percentage length或percentage就不用解釋了,長度和百分比是常常用的,接下來就用個例子來看看contain和cover的做用:

.lake {
  width: 300px;
  mask-image: url('../img/heart1.png');
  -webkit-mask-image: url('../img/heart1.png');
  mask-size: contain;
  -webkit-mask-size: contain;
}


contain表示遮罩將會被縮放,以在保存長寬比的同時填充圖片,若是遮罩長寬比與圖片長寬比不一致,將會重複繪製遮罩填充

.lake {
  width: 300px;
  mask-image: url('../img/heart1.png');
  -webkit-mask-image: url('../img/heart1.png');
  mask-size: cover;
  -webkit-mask-size: cover;
}


cover表示遮罩將會在保持框高比的狀況下充滿圖片,若是比例不一致,超出的部分將會被從頂部或者底部裁剪

mask-composite

mask-composite表示多圖片遮罩時,遮罩的合成展現效果,Firefox和Chrome支持的值還有點不太同樣,Chrome:clear|copy|destination-over|destination-in|destination-out|destination-atop|source-in|source-out|source-atop|source-over|xor|plus-lighter,在Chrome上支持的屬性實在是太多,不方便展開介紹,這裏有最全的介紹,還有具體的合成效果可查看
Firefox支持的值:add|subtract|intersect|exclude,這幾個屬性就能夠一塊兒來看看具體效果了:

.lake {
  width: 300px;
  mask-image: url('../img/star1.png'), url('../img/heart.png');
  -webkit-mask-image: url('../img/star1.png'), url('../img/heart.png');
  mask-composite: add;
  -webkit-mask-composite: add;
}


add的效果就是將兩個遮罩疊加

.lake {
  width: 300px;
  mask-image: url('../img/star1.png'), url('../img/heart1.png');
  -webkit-mask-image: url('../img/star1.png'), url('../img/heart1.png');
  mask-composite: subtract;
  -webkit-mask-composite: subtract;
}


subtract:兩個遮罩圖片重疊的部分會相互抵消

.lake {
  width: 300px;
  mask-image: url('../img/star1.png'), url('../img/heart1.png');
  -webkit-mask-image: url('../img/star1.png'), url('../img/heart1.png');
  mask-composite: intersect;
  -webkit-mask-composite: intersect;
}


intersect:兩個遮罩重疊的地方纔會顯示遮罩

.lake {
  width: 300px;
  mask-image: url('../img/star1.png'), url('../img/heart1.png');
  -webkit-mask-image: url('../img/star1.png'), url('../img/heart1.png');
  mask-composite: exclude;
  -webkit-mask-composite: exclude;
}


exclude:第二個遮罩與第一個遮罩重疊的部分遮罩變透明

瀏覽器支持

mask:

mask-image:

從瀏覽器支持程度能夠看到mask基本上都是部分支持,由於mask裏面涉及的一些屬性都是在不一樣瀏覽器有差別,可是mask-image屬性大多數瀏覽器都是徹底支持的,所以css mask在項目中徹底可使用,前提就是要注意不一樣屬性的瀏覽器支持程度,這和早期的flex佈局同樣,flex佈局相關的屬性一開始也是部分支持,後來瀏覽器支持度高了以後用起來真香,相信後面mask相關屬性也同樣

總結

寫這篇文章的目的主要是mask屬性確實很強大,可是當下的瀏覽器支持確實也很通常,記錄一下相關屬性在不一樣瀏覽器下的支持程度和用法,但願看了這篇文章對你們能有所幫助。若是有錯誤或不嚴謹的地方,歡迎批評指正,若是喜歡,歡迎點贊

相關文章
相關標籤/搜索