宣告多個蒙版

CSS 遮罩是一種技術,允許你使用影像作為遮罩來定義元素的哪些部分是完全可見或半透明的。CSS 遮罩根據應用遮罩影像的 alpha 通道,在某些情況下還會根據顏色的亮度,選擇性地顯示或隱藏元素的部分。

CSS 遮罩與假面舞會(戴面具的舞會)上戴的遮罩相反。在假面舞會上,佩戴者的臉在遮罩不透明的地方被隱藏,在透過遮罩可見的地方被顯示。在 CSS 中,組合遮罩層完全不透明的區域會顯示元素,而透明區域則隱藏元素。

CSS 遮罩由一個或多個遮罩層組成。在本指南中,我們將討論遮罩層的概念以及如何使用 mask 簡寫屬性宣告多個遮罩層。

理解遮罩層

你可以將 CSS 遮罩應用於所有 HTML 元素和大多數 SVG 元素。一個遮罩可以由一個或多個複合遮罩層組成。你可以在 mask 簡寫屬性或 mask-image 屬性中使用逗號分隔的值定義多個層——甚至設定為 none 的值也算作一個層。

每個遮罩層可以包含一個 遮罩影像,它相對於遮罩的起始框定位。影像可以調整大小、重複和裁剪。如果包含多個遮罩影像,則可以定義遮罩層的組合或合併方式。(本指南簡要介紹了這些功能。有關更多詳細資訊和示例,請參閱遮罩屬性指南。)

多遮罩層的語法

mask 簡寫屬性接受逗號分隔的遮罩層列表。每個層的語法可以包括以下值:

<image> <position> / <size> <repeat> <origin> <clip> <composite> <mode>

遮罩層中的所有元件都是可選的。但是,如果你省略 mask-image 值,它將預設為透明黑色影像,這會完全隱藏該層中的元素。

mask 簡寫宣告設定所有 mask-* 屬性的值。層內未宣告的任何元件都將預設為其初始值。mask 屬性還會將所有 mask-border-* 屬性重置為其初始值。僅包含 mask-image 值的 mask 宣告隱式設定以下內容:

css
mask-mode: match-source;
mask-position: 0% 0%;
mask-size: auto;
mask-repeat: repeat;
mask-origin: border-box;
mask-clip: border-box;
mask-composite: add;

mask-border-source: none;
mask-border-mode: alpha;
mask-border-outset: 0;
mask-border-repeat: stretch;
mask-border-slice: 0;
mask-border-width: auto;

使用 mask-image 定義遮罩層

只要逗號分隔的 mask-image 屬性宣告中包含至少一個非 none 的值,就會為宣告中的每個值建立一個遮罩層,即使是 none 值也是如此。無論你使用 mask-image 屬性還是 mask 簡寫,此行為都適用。這些遮罩影像可以是漸變、影像或 SVG 源。你可以使用 CSS 漸變、點陣圖影像(如 PNG)或 SVG <mask> 元素來定義它們。

css
.gradient-mask {
  mask-image: linear-gradient(to right, black, transparent);
}

.raster-mask {
  mask-image: url("alphaImage.png");
}

.mask-element-mask {
  mask-image: url("#svg-mask");
}

遮罩入門指南介紹了不同型別的遮罩影像及其模式。

mask-image 屬性類似於 background-image 屬性。與 background-image 屬性一樣,要包含多個遮罩影像,影像值用逗號分隔。

css
.multiple-gradient-mask {
  mask-image:
    linear-gradient(to right, black, transparent),
    radial-gradient(circle, white 50%, transparent 75%);
}

多影像宣告中的每個遮罩影像都會建立一個遮罩層。本節中的所有示例都建立一個遮罩層,除了 multiple-gradient-mask 宣告,它建立兩個。

遮罩層和 none 關鍵字

如果 nonemask-image 屬性的唯一值,則不會建立遮罩層,也不會發生遮罩。

css
.no-masks {
  mask-image: none;
}

類似地,在使用 mask 簡寫時,如果除了 none 之外沒有 mask-image 值,則不會發生遮罩。如果聲明瞭以下任何一項,則不會建立遮罩層,也不會隱藏任何內容:

css
mask: none;
mask: none 100px 100px no-repeat;
mask: 100px 100px no-repeat;

否則,只要聲明瞭非 nonemask-image,就會為逗號分隔值列表中的每個值建立一個遮罩層,即使 mask-image 值在逗號分隔值列表中被省略或明確設定為 none 也是如此。換句話說,除非整個屬性解析為 none,否則會為每個有效的逗號分隔值建立一個層。

css
.masked-element {
  mask-image:
    url("alphaImage.png"), linear-gradient(to right, black, transparent),
    radial-gradient(circle, white 50%, transparent 75%), none, url("#svg-mask");
}

遮罩源列表中的關鍵字 none 會建立一個遮罩層,儘管是一個透明的黑色影像層。任何帶有 masked-element 類的元素都將有五個遮罩層:

我們也可以使用 mask 簡寫建立這些層:

css
.masked-element {
  mask:
    url("alphaImage.png"), linear-gradient(to right, black, transparent),
    radial-gradient(circle, white 50%, transparent 75%), none, url("#svg-mask");
}

如果逗號分隔值列表中的值是空影像,下載失敗,引用不存在的 <mask> 元素,或者以其他方式無法顯示(或設定為 none),它仍然算作一個遮罩影像層,渲染一個沒有視覺效果的透明黑色遮罩影像。如果所有值都這樣做,元素將完全隱藏。

如果整個屬性解析為 none,則不會發生遮罩,這使得元素完全可見。另一方面,如果該值包含多個層並且至少一個不是 none,則 none 層不會顯示元素的任何部分(或不會使元素的任何部分可見)。在此示例中,該值不會解析為 none;但由於所有非 none 影像都無效,因此會發生遮罩,並且元素將完全隱藏。

none 的計算值會建立一個 CSS 堆疊上下文

遮罩層如何影響 mask-* 屬性

當你還在 mask 宣告之後或使用比 mask 宣告更具體的個別 mask-* 屬性時,遮罩層的數量很重要。

mask-* 屬性包括:

  • mask-mode:將每個遮罩層的模式設定為 alphaluminance,或透過將值設定為 match-source 允許它預設為源的模式。預設值為 match-source

  • mask-position:類似於 background-position 屬性,其語法遵循 background-position<position> 語法,它設定遮罩影像相對於遮罩層起始框(由 mask-origin 屬性定義)的初始位置。你可以指定一個、兩個或四個 <position> 值。預設的 0% 0% 將遮罩的左上角定位在遮罩起始框的左上角。

  • mask-origin:類似於 background-origin 屬性,它指定遮罩定位區域,即遮罩影像定位在其內的遮罩起始框區域。例如,如果 mask-positiontop left,此屬性定義它是否相對於邊框的外邊緣、內邊距的外邊緣或內容的外邊緣。

  • mask-clip:類似於 background-clip 屬性,它確定受遮罩影響的元素區域。它定義遮罩繪製區域是邊框、內邊距還是內容框,將元素的繪製內容限制在此區域。如果遮罩層的 mask-image 源是 SVG <mask> 元素,則 mask-clip 屬性無效。

  • mask-size:類似於 background-size 屬性,用於調整遮罩層的大小。值可以是單個關鍵字(covercontainauto),單個長度或百分比,或兩個空格分隔的值——每個值都可以是長度、百分比或 auto。預設值為 auto

  • mask-repeat:類似於 background-repeat 屬性,它定義了遮罩層影像在調整大小和定位後如何平鋪。

  • mask-composite:定義遮罩如何與下面的遮罩層組合。每個遮罩層要麼新增到、減去、包含或排除於其下面的先前組合的遮罩層。與 mask-mode 類似,沒有類似的 background-* 屬性。

逗號分隔的 mask 元件屬性列表中的每個 mask-* 值都應用於一個單獨的遮罩層。如前所述,一個元素可以應用多個遮罩層——層的數量由 mask-imagemask 屬性中逗號分隔值的數量決定。每個 mask-* 值都按順序與一個遮罩層匹配。如果 mask-* 屬性中的值數量大於遮罩層的數量,則任何多餘的值都將被忽略。如果遮罩元件屬性的值少於遮罩層的數量,則 mask-* 值會重複。

要了解有關這些單個屬性的更多資訊,請參閱 CSS 遮罩屬性

簡寫元件屬性的順序

在大多數情況下,屬性的順序是靈活的,但有一些怪癖和例外。

mask-originmask-clip 的排序規則

在語法中列為 <origin>mask-origin 值位於在語法中列為 <clip>mask-clip 值之前。

<image> <position> / <size> <repeat> <origin> <clip> <composite> <mode>

兩者都接受 <geometry-box> 關鍵字。此外,mask-clip 還接受 no-clip。因此,當你希望將 mask-clip 設定為 no-clip 之外的任何值時,這兩者的順序很重要。

  • 如果存在一個 <geometry-box> 值以及 no-clip 關鍵字,則 <geometry-box> 設定 mask-origin 值,並且 mask-clip 設定為 no-clip。在這種情況下,順序無關緊要。

  • 如果只存在一個 <geometry-box> 值並且沒有 no-clip 關鍵字,則 mask-originmask-clip 元件都設定為該值。由於只有一個值,因此順序再次無關緊要。

  • 如果存在兩個 <geometry-box> 值,則第一個設定 mask-origin 元件,第二個設定 mask-clip 元件。在這種情況下,順序非常重要。

mask-originmask-clip 值設定順序不正確可能會影響外觀,但不會導致宣告失敗。

mask-sizemask-position 的排序規則

你可能已經注意到 mask-positionmask-size 之間有一個斜槓,在語法中列為 <position><size>。這兩個屬性接受相似的值。

<image> <position> / <size> <repeat> <origin> <clip> <composite> <mode>

在這種情況下,順序非常重要。如果只存在一個或一對 <length-percentage> 值,它將定義影像的位置而不是大小。在遮罩層中同時包含位置和大小而不包含兩者之間的斜槓將使整個宣告無效。

css
mask:
  url("star.svg") bottom 2em right 4em / auto 2vw no-repeat padding-box
    content-box luminance,
  url("circle.svg") 100px 100px / 50% repeat-x border-box padding-box alpha;

如果存在單個 <length-percentage> 值對,它將設定 mask-position 屬性,並且 mask-size 將為 auto。如果一個層同時包含 mask-sizemask-position,則 mask-size 屬性值必須在 mask-position 屬性值之後,並且值之間必須用正斜槓 (/) 分隔。即使 mask-size 設定為不是有效 mask-position 值的值,也需要斜槓。

css
mask: url("star.svg") contain;
mask: url("star.svg") 10px 10px cover;
mask: url("star.svg") top right 100px 100px;
css
mask: url("star.svg") 10px 10px / cover;
mask: url("star.svg") top 100px right 100px;
mask: url("star.svg") top right / 100px 100px;

要在使用 mask 簡寫宣告的遮罩層中包含 mask-size,你必須在它之前緊接著包含一個帶有斜槓的 mask-position 值。

警告:如果你在遮罩層中包含大小但忘記了位置後面的斜槓,則整個宣告將變為無效。

另見