CSS 遮罩属性

CSS 遮罩是一种技术,通过应用一个遮罩,根据所应用的遮罩图像的 alpha 通道(以及可选的颜色)选择性地显示或隐藏元素的部分,从而定义元素的可见部分。

遮罩入门指南介绍了不同类型的遮罩图像及其模式。关于声明多个遮罩的指南讨论了遮罩层mask 简写属性,简要介绍了简写属性的各个分量属性。在本指南中,我们将更详细地探讨这些分量属性,并看看它们如何相互作用。我们还将解释,在声明了多个遮罩图像的情况下,遮罩层是如何合成或组合的。

CSS 遮罩由一个或多个遮罩层组成,对于以逗号分隔的 maskmask-image 值列表中的每个值,都会创建一个遮罩层,无论这些值是图像、遮罩源还是关键字 none。每个 mask-image 都相对于一个原点框进行定位。遮罩图像可以被调整大小重复裁剪,然后与前面的图层合成在一起,以在元素上创建最终的视觉遮罩。

mask-image 属性

创建遮罩的最低要求是将 mask-image 属性设置为 none 以外的值。在遮罩源列表中的关键字 none 会创建一个遮罩层。但是,如果 nonemask-image 属性的唯一值,则不会发生遮罩。

遮罩图像可以是 CSS 渐变导入的图像(如 PNG、SVG 等),或 SVG <mask> 元素。

在这个例子中,我们创建了五个遮罩层,包括一个导入的图像、两个渐变、一个没有图像的层,以及一个 SVG <mask> 源作为遮罩图像。

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 元素,但创建了五个遮罩层。

none 的重要性

none 层通常没有视觉效果(参见 mask-composite 属性了解它如何影响应用的遮罩),但由于以逗号分隔的 mask-* 值列表中的每个值都应用于一个单独的遮罩层,因此即使它不改变合成的遮罩,none 值也起着重要作用。

在我们五层结构中的第四层将匹配任何其他以逗号分隔的 mask-* 属性值中的第四个值。如前所述,层的数量由 mask-image 属性值中以逗号分隔的值的数量决定,即使某个值为 none。每个 mask-* 的值都按顺序与 mask-image 的值匹配。如果 mask-* 属性中的值的数量与遮罩层的数量不同,任何多余的值都将被忽略,或者,如果属性的值少于遮罩层的数量,这些值将被重复。

如果一个 mask-* 属性只有一个值,这个值将应用于所有的层。如果我们有五个值,第四个值将应用于 none 层,最后一个值将应用于 <mask> 源层。如果有两个以逗号分隔的值,第一个值将仅应用于所有奇数层,包括那个 <mask> 源层。例如,每个 mask-* 属性可以有不同数量的值。

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");
  mask-repeat: repeat-x, repeat-y;
  mask-position:
    center,
    top left,
    bottom right;
}

在这种情况下,每个奇数层将在 x 轴上重复,而每个偶数层将在 y 轴上重复。第一和第四层图像将居中,而第二和第五层将位于左上角。none 意味着第五层的 #svg-mask 图像将从左上角开始沿 x 轴重复。

了解更多关于遮罩层和 none 关键字的信息。

mask-mode 属性

mask-mode 属性可以用来将每个遮罩层的模式设置为 alphaluminance,或者通过将值设置为 match-source(默认值)来使其默认为源的模式。虽然大多数 mask-* 属性都有一个类似的 background-* 属性(例如,mask-image 类似于 background-image 属性),但 mask-modemask-composite 没有类似的 background 属性。

遮罩类型:alphaluminance

每个遮罩要么是 alpha 遮罩,要么是 luminance 遮罩。

对于 alpha 遮罩,每个遮罩像素的 alpha 透明度很重要。遮罩不透明的地方,元素的相应部分将是可见的。遮罩透明的地方,元素的相应部分将被隐藏。遮罩半透明的地方,元素也将同样半透明。遮罩的颜色不重要,只有颜色的 alpha 透明度重要。

对于 luminance 遮罩,遮罩颜色的亮度和 alpha 通道都决定了被遮罩区域的不透明度。

注意:后续所有示例都使用以下图像作为元素的 background-image,我们将对该元素应用遮罩。

Pride flag

这个例子演示了 alphaluminance 遮罩之间的区别。遮罩是相同的,但在 alpha 遮罩中,只有渐变遮罩颜色的 alpha 透明度重要。在 luminance 示例中,R、G、B 和 A 都很重要。

两个容器包含图像,最后一个是空的,但包含在内以显示我们将用作 mask-image 的渐变。

html
<div class="alpha">
  <img
    src="https://mdn.github.io/shared-assets/images/examples/progress-pride-flag.jpg"
    alt="Pride flag" />
</div>
<div class="luminance">
  <img
    src="https://mdn.github.io/shared-assets/images/examples/progress-pride-flag.jpg"
    alt="Pride flag" />
</div>
<div class="gradient"></div>

我们声明了一个带有红色、透明和半透明红色对角条纹的 repeating-linear-gradient。这个渐变被用作我们的遮罩,并且对于最后一个容器,用作背景图像。

css
img {
  mask-image: repeating-linear-gradient(
    to bottom right,
    red 0 20px,
    #ff000055 20px 40px,
    transparent 40px 60px
  );
}
.gradient {
  background: repeating-linear-gradient(
    to bottom right,
    red 0 20px,
    #ff000055 20px 40px,
    transparent 40px 60px
  );
}

我们为每个图像设置了不同的 mask-mode 属性值。

css
.alpha img {
  mask-mode: alpha;
}

.luminance img {
  mask-mode: luminance;
}

alpha 情况下,只有渐变颜色的透明度重要。渐变为不透明红色的地方,图像就不透明。渐变为透明的地方,图像就被隐藏。渐变为 50% 不透明的地方,图像就 50% 不透明。在 luminance 情况下,颜色的亮度很重要!请参阅Alpha 透明度与亮度来了解使用颜色 R、G、B 和 A 通道确定遮罩不透明度的方程式。

mask-mode 的默认值:match-source

mask-mode 属性的默认值是 match-source。这个值会将 mask-mode 设置为与遮罩的模式类型相匹配。除了遮罩源是 SVG <mask> 元素的情况外,match-source 值会解析为 alpha

当使用 SVG <mask> 元素作为遮罩源时,match-source 值会解析为 <mask> 元素的 mask-type 属性的值。如果 <mask> 元素(而不是“被遮罩的元素”)没有定义 CSS mask-type 属性,该属性将默认为 SVG mask-type 属性的值(如果存在)。如果该属性也被省略,match-source 值将解析为 luminance

继续 masked-element 示例,如果我们没有明确设置 mask-mode 属性,它将对每个层默认为 match-source,就好像我们设置了以下内容:

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");
  mask-mode: match-source;
}

或者,使用 mask 简写:

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

第一个遮罩层 url("alphaImage.png") 引用了一个图像。由于这不是 <svg> 中的 <mask> 元素,mask-mode 解析为 alpha,该图像的不透明部分使元素的相应部分可见,而透明或半透明部分则不可见或部分可见。

linear-gradient(to right, black, transparent) 是第二个遮罩层,radial-gradient(circle, white 50%, transparent 75%) 是第三个。同样,这些不是 <mask> 元素,所以 match-source 值解析为 alpha。这些层的遮罩效果默认由渐变遮罩的不透明度决定。

第四个遮罩层声明了 none,这意味着该层的遮罩是透明黑色。.masked-element 类设置了 mask-mode: match-source;。如果 mask-mode 是一个包含五个不同值的逗号分隔列表,第四个值将应用于这个 none 层,从而允许第五个值应用于第五层。

第五个遮罩层由一个 SVG <mask> 元素组成,其 idsvg-mask。虽然其他层的默认遮罩模式是 alpha,但 SVG <mask> 元素的默认遮罩类型mask-type 的值,或者如果未设置,则是 mask-type 属性。如果该属性也未定义,则该值默认为 luminance。换句话说,<mask> 的遮罩效果由 <mask> 元素颜色的亮度和透明度共同决定。

如果我们根本不声明 mask-mode 属性,并让它对每个遮罩层默认为 match-source,那么在这个 .masked-element 案例中,结果将解析为:

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");
  mask-mode: alpha, alpha, alpha, match-source, luminance;
}

或者,使用 mask 简写:

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

mask-position 属性

类似于 background-position 属性,mask-position 属性设置遮罩图像相对于遮罩层原点框的初始位置,该原点框由 mask-origin 属性定义。其语法遵循 background-position<position> 语法,值为一个、两个或四个 <position> 值,定义一到两个相对或绝对位置偏移。

单值语法

如果只指定一个关键字值,该值指定遮罩将放置的遮罩原点边缘,另一个维度为 center

如果只指定一个 <length-percentage> 值,这指定了相对于遮罩原点左边缘的 X 坐标,Y 坐标设置为 50%

如果指定了两个关键字值,值的顺序不重要,但值不能包含两个垂直或两个水平轴的值;left righttop bottom 都是无效的。

双值语法

如果存在两个值,包括一个关键字和一个 <length-percentage> 值,顺序仅在关键字是 center 时才重要。

  • 如果关键字是 leftright,它定义了相对于左边缘的 X 坐标,另一个值定义了相对于上边缘的 Y 坐标。
  • 类似地,topbottom 关键字定义了将元素分别定位在上边缘或下边缘的 Y 坐标,另一个值定义了相对于遮罩原点框左边缘的 X 值。
  • 当一个值是 center 关键字,另一个是 <length-percentage> 时,第一个值定义水平位置,第二个值定义垂直位置。

如果存在两个值且都是 <length-percentage> 值,顺序再次重要;第一个值定义了相对于遮罩定位区域左边缘偏移的水平位置,而第二个值定义了相对于遮罩定位区域上边缘偏移的垂直位置。

四值语法

遮罩位置也可以相对于除左上角以外的角。四值语法允许从任何角偏移遮罩。该值包括两个 <length-percentage> 偏移量,每个偏移量前面都有该偏移量的原点边。先声明水平对还是垂直对并不重要,但你必须在每对中的偏移量 <length-percentage> 之前声明原点边关键字(leftrighttopbottomx-startx-endy-starty-endblock-startblock-endinline-startinline-end),并且两个原点边不能来自同一轴。

在两个 <length-percentage> 的语法中,原点边按顺序是 topleft。例如,mask-position: 10px 20px 等同于 mask-position: left 10px top 20px。当从顶部和左侧偏移时,不需要指定偏移边,但顺序很重要。使用四值语法,你可以使用 mask-position 从任何边的组合来偏移遮罩图像,例如 left 10px bottom 20px,并且边的顺序不重要,因为偏移边由其前面的关键字而不是声明顺序来定义。

百分比值

当使用百分比值进行偏移时,遮罩的尺寸会从元素的尺寸中减去,就像使用 background-position 的百分比偏移一样。

定位重复的遮罩图像

mask-position 属性定义了遮罩图像的初始位置。所谓“初始位置”,如果遮罩重复,浏览器会将第一个遮罩图像放置在 mask-position 属性定义的位置,从而定义遮罩重复的布局。

在这个例子中,我们将第一张图像的位置设置为 bottom right,这意味着第一个遮罩将被放置在遮罩原点框的右下边缘。因为遮罩图像默认是重复的,所以重复的遮罩将相对于第一个放置的遮罩的顶部和左侧进行定位。

css
img {
  mask-image: url("https://mdn.github.io/shared-assets/images/examples/mask-star.svg");
}
.keywords img {
  mask-position: bottom right;
}
.twoValue img {
  mask-position: -20px -10px;
}
.fourValue img {
  mask-position: right -20px bottom -10px;
}

mask-position 定义了第一个遮罩图像的放置位置。这个演示展示了第一个图像被放置在哪里:

因为 mask-repeat 属性的默认值是 repeat,所以图像会根据第一个遮罩的位置沿 X 和 Y 轴重复。

双值示例定义了原始遮罩的顶部和左侧偏移。四值示例结合了前面两个示例,使用与第二个图像相同的偏移量来定位第一个遮罩,但从第一个图像中演示的相同边缘开始。

在第一张图片中,首先被放置的星星是右下角的那颗,重复的星星在它的上方和左侧。由于这种定位,初始的星星没有被裁剪,但最顶部和最左侧的星星被裁剪了。

如果我们没有明确设置 mask-position 属性,它将对每个层默认为 0% 0%,即遮罩的左上角与遮罩原点框的左上角对齐。继续 masked-element 示例,就好像我们设置了以下内容:

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");
  mask-mode: match-source;
  mask-position: 0% 0%;
}

或者,使用 mask 简写来扩展示例:

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

mask-origin 属性

当一个元素有内边距、边框或两者都有时,mask-origin 属性定义了这些框边缘值中的哪一个作为遮罩原点框,即遮罩定位区域,遮罩图像在该层内被定位。mask-origin 属性类似于 background-origin 属性,但具有不同的初始值和仅适用于 SVG 的值。

HTML 元素的遮罩可以包含在其内容边框框、内边距框或内容框内。例如,如果 mask-positiontop left,那是相对于边框的外边缘、内边距的外边缘还是内容的外边缘?

mask-position 遮罩示例中,定义的位置是相对于边框盒(默认行为),尽管值得注意的是,<img> 没有设置边框或内边距,因此在这种情况下,内容盒、内边距盒和边框盒的原点都是相同的。

在这个例子中,mask-position 将初始遮罩放置在具有大边框和内边距的 <img> 元素的左上角,并带有绿色背景色,以便能够在内边距区域看到星星遮罩。

css
img {
  mask-image: url("https://mdn.github.io/shared-assets/images/examples/mask-star.svg");
  mask-position: top left;
  padding: 15px;
  border: 15px solid;
  background-color: green;
}
:has(#origin_border-box:checked) img {
  mask-origin: border-box;
}
:has(#origin_padding-box:checked) img {
  mask-origin: padding-box;
}
:has(#origin_content-box:checked) img {
  mask-origin: content-box;
}

通过更改所选的单选按钮来更改 mask-origin 属性的值,并在这样做时观察左上角星星遮罩的位置。

默认值是 border-box。使用这个值,初始遮罩被放置在边框的左上边缘并且不会被裁剪。当初始遮罩被放置在内边距的外部或内部边缘时,它的上方和左侧有空间;这些重复的遮罩会被裁剪。

继续 masked-element 示例,如果我们没有明确设置 mask-origin 属性,它将对每个层默认为 border-box,就好像我们设置了以下内容:

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");
  mask-mode: match-source;
  mask-position: 0% 0%;
  mask-origin: border-box;
}

或者,使用 mask 简写来扩展示例:

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

对于没有相关 CSS 布局框的 SVG 元素,遮罩可以包含在 SVG 元素的填充、描边或视口框内。

mask-clip 属性

mask-clip 属性决定了元素中受遮罩影响的区域,有效地在定义的框边缘处裁剪元素。它类似于 background-clip 属性,但有一些不同的值。

因为 mask-clip 属性接受所有 mask-origin 的值,并且两者都有相同的 border-box 默认值,所以这两个属性可能看起来很相似,但它们的用途非常不同。mask-origin 决定了遮罩图像将被放置在哪里,而 mask-clip 属性则导致原始元素的内容被裁剪到指定的框。理解它们两者都很重要:如果 mask-origin 导致 mask-position 将遮罩图像放置在裁剪区域之外,那么遮罩将被裁剪。

mask-clip 属性接受所有 mask-origin 的值,以及它自己的 no-clip 值。no-clip 值设置绘制的内容不被裁剪。你仍然可以通过使用小于零或解析为大于 100% 的 mask-position 值将遮罩图像定位在边框内容区域之外来使其被裁剪。

mask-clipmask-origin 设置为不同的值可能会导致遮罩层图像被裁剪。例如,如果一个带有边框和内边距的元素将 mask-clip 设置为 content-boxmask-origin 设置为 border-box,并且 mask-position 设置为 top left 边缘,那么遮罩层图像将在左上边缘被裁剪。

下一个示例在前一个示例中添加了裁剪选项,以演示不同的非 SVG mask-clip 值,并展示它们如何影响不同的 mask-origin 值。

css
:has(#clip_border-box:checked) img {
  mask-clip: border-box;
}
:has(#clip_padding-box:checked) img {
  mask-clip: padding-box;
}
:has(#clip_content-box:checked) img {
  mask-clip: content-box;
}

第一个遮罩被放置在遮罩原点容器的左上边缘,然后重复。如果原点框是 border-box 而裁剪区域是 content-box,那么遮罩原点容器的顶部和左侧区域将被裁剪。通常,你会希望 mask-clipmask-origin 相同。

继续 masked-element 示例,如果我们没有明确设置 mask-clip 属性,它将对每个层默认为 border-box,就好像我们设置了以下内容:

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");
  mask-mode: match-source;
  mask-position: 0% 0%;
  mask-origin: border-box;
  mask-clip: border-box;
}

或者,使用 mask 简写来扩展示例:

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

mask 简写中,如果只给出一个 <geometry-box> 值,它会同时设置 mask-originmask-clip 属性值。如果存在两个 <geometry-box> 值,第一个定义 mask-origin,第二个定义 mask-clip

对于不引用 SVG <mask> 元素的遮罩层图像,mask-clip 属性定义了遮罩绘制区域,即受遮罩影响的区域,是边框、内边距还是内容框。元素的绘制内容将被限制在该区域内。

当遮罩层的 mask-image 源是 <mask> 时,mask-clip 属性没有效果。相反,<mask> 元素的 xywidthheightmaskUnits 属性决定了遮罩绘制区域。

mask-size 属性

mask-size 属性用于调整遮罩层的大小。此属性类似于 background-size 属性,接受相同的值。调整遮罩大小时,请记住元素中未被遮罩图像覆盖的区域是隐藏的。

有三种方式可以声明 mask-size

  • covercontain 关键字,
  • 一个长度、百分比或关键字 auto,或
  • 两个值的组合,可以是长度、百分比和关键字 auto

遮罩图像可以保持其自然大小、被拉伸或被约束以适应可用空间。遮罩图像的宽高比默认保持不变,但声明两个 <length-percentage> 值可能会扭曲遮罩图像,如果这两个值的比例与原始图像不同(mask-repeat: round 是另一个可能扭曲遮罩图像的属性/值对)。

如果 mask-size 设置为 contain,遮罩图像将是其在完全包含在遮罩定位区域内所能达到的最大尺寸。在这种情况下,遮罩图像不会被裁剪,而是被完全包含。

当设置为 cover 时,遮罩图像将是其完全覆盖整个遮罩定位区域所能达到的最小尺寸,如果遮罩的宽高比与遮罩定位区域的宽高比不同,遮罩将被裁剪。

换句话说,使用 covercontain,遮罩的至少一个维度将与遮罩定位区域的相同维度大小相同;遮罩图像会放大或缩小,使得其宽度与遮罩定位区域的宽度相同,或者遮罩图像的高度等于遮罩定位区域的高度。

使用 covercontain<percentage> 值时,大小是相对于原点框的。在我们的星星遮罩和旗帜图像示例中,遮罩图像和 <img> 的宽高比都是 1:1,这意味着在这种情况下,covercontain100% 都会产生相同大小的遮罩。这个例子演示了当 mask-size 设置为 covercontain<percentage> 值时,遮罩的实际大小可能会根据 mask-origin 属性的值而有所不同。

css
img {
  mask-size: 100%;
}
:has(#border-box:checked) img {
  mask-origin: border-box;
}
:has(#padding-box:checked) img {
  mask-origin: padding-box;
}
:has(#content-box:checked) img {
  mask-origin: content-box;
}

更改 mask-origin 属性的值,看看不同的值如何影响遮罩的大小。

这个例子包含了一个 <percentage> 值。当指定一个 <length-percentage> 值时,它只定义遮罩的宽度,高度默认为 auto,这会保持宽高比。当指定两个值时,第一个定义遮罩的宽度,第二个定义其高度。

mask-size 的默认值是 auto,这会以其固有尺寸渲染遮罩,即如果没有应用 CSS,遮罩将显示的尺寸。如果你设置单个 <length-percentage> 值,或者两个值的比例与宽高比相同,则会保持遮罩图像的底层宽高比。如果你声明的两个值的比例与宽高比不同,遮罩图像会被扭曲。

与简写属性的所有普通分量属性一样,如果设置了 mask 简写属性,并且在任何遮罩层中没有定义 mask-size 属性的值,那么 mask-size 的值将为这些遮罩层重置为其初始值 auto

如果图像没有固有比例,例如 CSS 渐变,默认的 auto 是由 mask-origin 属性设置的整个遮罩定位区域。

继续 masked-element 示例,如果我们没有明确设置 mask-size 属性,它将对每个层默认为 auto,就好像我们设置了以下内容:

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");
  mask-mode: match-source;
  mask-position: 0% 0%;
  mask-origin: border-box;
  mask-clip: border-box;
  mask-size: auto;
}

或者,使用 mask 简写来扩展示例,mask-size 分量跟在 mask-position 值之后,用正斜杠 (/) 分隔:

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

mask-repeat 属性

mask-repeat 属性定义了在初始遮罩图像被调整大小和定位后,遮罩图像如何重复或平铺。mask-repeat 属性定义了该遮罩图像是否以及如何沿水平和垂直轴重复。在之前的大多数示例中,你可能已经注意到星星遮罩沿 X 和 Y 轴重复。这是因为 repeat 是默认值。

mask-repeat 属性类似于 background-repeat 属性,接受相同的 <repeat-style> 值。与 background-repeat 的情况一样,第一个(也可能是唯一的)遮罩图像重复由 *-position 属性定位,并由 *-size 属性调整大小。重复的背景或遮罩图像的位置是基于这个初始图像实例的。

继续 masked-element 示例,如果我们没有明确设置 mask-repeat 属性,它将对每个层默认为 repeat,就好像我们设置了以下内容:

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");
  mask-mode: match-source;
  mask-position: 0% 0%;
  mask-origin: border-box;
  mask-clip: border-box;
  mask-size: auto;
  mask-repeat: repeat;
}

或者,使用 mask 简写来扩展示例:

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

mask-composite 属性

mask 简写包含了 mask-composite 属性,它定义了多个遮罩如何组合以创建最终的遮罩效果。以逗号分隔的值列表中的每个值决定了浏览器应该将关联的遮罩层与它下面的遮罩层进行 add(相加)、subtract(相减)、intersect(相交)还是 exclude(排除)。与 mask-mode 和其他 mask-* 属性类似,background 简写中没有与之类似的属性。

在这个例子中,我们包含了两个 mask-image 值,包括之前示例中的星星和渐变作为遮罩图像。

css
img {
  mask-image:
    repeating-linear-gradient(
      to bottom right,
      red 0 20px,
      #ff000055 20px 40px,
      transparent 40px 60px
    ),
    url("https://mdn.github.io/shared-assets/images/examples/mask-star.svg");
}

我们为每个图像设置了不同的 mask-composite 值。

css
.add img {
  mask-composite: add;
}
.subtract img {
  mask-composite: subtract;
}
.intersect img {
  mask-composite: intersect;
}
.exclude img {
  mask-composite: exclude;
}

半透明的星星遮罩会根据 mask-composite 的值,与条纹遮罩相加、相减、相交或排除。

mask-composite 属性仅在有两个或更多遮罩层的情况下才相关。这里说的是“遮罩层”,而不是“遮罩图像”,因为如果包含 none,透明的黑色遮罩也会被合成。在 subtractintersect 的情况下,none 值会对遮罩产生深远的影响。例如,如果 mask-mode 解析为 luminance,减去一个黑色遮罩将移除整个遮罩(元素将被隐藏)。类似地,如果 none 是最后一层,并且该层的 mask-composite 设置为 intersect,整个元素将被隐藏。这里,我们在前面的例子中添加了第三层,值为 none

css
img {
  mask-image:
    url("https://mdn.github.io/shared-assets/images/examples/mask-star.svg"),
    repeating-linear-gradient(
      to bottom right,
      red 0 20px,
      #ff000055 20px 40px,
      transparent 40px 60px
    ),
    none;
}

注意 intersect 示例如何排除了所有内容,因为透明的黑色遮罩不与任何东西相交。

如果我们颠倒遮罩层的顺序,我们也可以得到非常不同的结果。

css
.gradientFirst {
  mask-image:
    repeating-linear-gradient(
      to bottom right,
      red 0 20px,
      #ff000055 20px 40px,
      transparent 40px 60px
    ),
    url("https://mdn.github.io/shared-assets/images/examples/mask-star.svg");
}
.starFirst {
  mask-image:
    url("https://mdn.github.io/shared-assets/images/examples/mask-star.svg"),
    repeating-linear-gradient(
      to bottom right,
      red 0 20px,
      #ff000055 20px 40px,
      transparent 40px 60px
    );
}

在第一个例子中,星星从条纹中减去。在第二个例子中,条纹从星星中减去。

与所有其他 mask 分量属性一样,mask-composite 接受一个以逗号分隔的值列表。由于该属性影响遮罩的组合方式,因此该属性仅与多个遮罩层相关,并且使用的值的数量比遮罩层的数量少一个。

最后一对遮罩首先被合成。然后,前一个遮罩图像与前一次的合成结果进行合成。

继续 masked-element 示例,如果我们没有明确设置 mask-composite 属性,它将对每个层默认为 add,就好像我们设置了以下内容:

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");
  mask-mode: match-source;
  mask-position: 0% 0%;
  mask-origin: border-box;
  mask-clip: border-box;
  mask-size: auto;
  mask-repeat: repeat;
  mask-composite: add;
}

在这种情况下,<mask> 元素将与 none 层合成。然后径向渐变将与前一次合成的结果合成,依此类推。

就像我们看到的所有其他分量属性一样,我们可以使用 mask 简写:

css
.masked-element {
  mask:
    url("alphaImage.png") 0% 0% / auto repeat border-box border-box add
      match-source,
    linear-gradient(to right, black, transparent) 0% 0% / auto repeat border-box
      border-box add match-source,
    radial-gradient(circle, white 50%, transparent 75%) 0% 0% / auto repeat
      border-box border-box add match-source,
    none 0% 0% / auto repeat border-box border-box add match-source,
    url("#svg-mask") 0% 0% / auto repeat border-box border-box add match-source;
}

另见