CSS遮罩的语法

功能:让一个元素按照某张图像的轮廓显示
兼容性:需使用-webkit-私有前缀

mask-image 遮罩图片

支持多图片,所有<image>数据类型的值都可以作为遮罩图像

半透明的PNG图像遮罩

CSS遮罩【详解】_css


效果见 ​​https://demo.cssworld.cn/new/12/1-1.php​

<img src="nature-8.jpg" class="mask-image" width="256" height="192">
.mask-image {
-webkit-mask: no-repeat center / contain;
mask: no-repeat center / contain;
-webkit-mask-image: url(../images/bird.png);
mask-image: url(../images/bird.png);
}

SVG图形遮罩

使用url()函数直接内联SVG代码

CSS遮罩【详解】_css_02


效果见 ​​https://demo.cssworld.cn/new/12/1-2.php​

<img src="8.jpg" class="mask-image" width="256" height="174">
.mask-image {
--svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Cpath d='M28.027 5.161l-17.017 17.017-7.007-7.007-3.003 3.003 10.010 10.010 20.020-20.020z'%3E%3C/path%3E%3C/svg%3E");

-webkit-mask-image: var(--svg);
mask-image: var(--svg);

-webkit-mask-repeat: no-repeat;
mask-repeat: no-repeat;
}

将图片改成颜色填充的div,可用于实现方便变色的svg图标

CSS遮罩【详解】_css_03

<template>
<div class="myIcon ok_SVG_mask"></div>
</template>

<style scoped>.myIcon {
background-color: blue;
width: 100px;
height: 100px;
}

.ok_SVG_mask {
--svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Cpath d='M28.027 5.161l-17.017 17.017-7.007-7.007-3.003 3.003 10.010 10.010 20.020-20.020z'%3E%3C/path%3E%3C/svg%3E");

-webkit-mask-image: var(--svg);
mask-image: var(--svg);

-webkit-mask-repeat: no-repeat;
mask-repeat: no-repeat;
}</style>

渐变图像遮罩

最常用的,也是最实用的,因为相比url()函数外链的图像,其资源开销小,开发成本低,维护更加方便。

CSS遮罩【详解】_css_04


效果见 ​​https://demo.cssworld.cn/new/12/1-3.php​

<img src="1.jpg" class="mask-image" width="256" height="192">
.mask-image {
--gradient1: radial-gradient(600px 80px at top, transparent 150px, black 152px 1000px, transparent 0);
--gradient2: radial-gradient(600px 80px at bottom, transparent 150px, black 152px 1000px, transparent 0);
-webkit-mask-image: var(--gradient1), var(--gradient2);
mask-image: var(--gradient1), var(--gradient2);
}

SVG图形中<mask>元素作为遮罩图像

CSS遮罩【详解】_3c_05


效果见 ​​https://demo.cssworld.cn/new/12/1-5.php​

<svg style="position: absolute; width: 0; height: 0;"> 
<mask id="mask" maskContentUnits="objectBoundingBox">
<ellipse cx=".5" cy=".5" rx=".4" ry=".2" fill="white"></ellipse>
<rect x=".3" y=".1" width=".4" height=".8" rx=".1" ry=".1" fill="white"></rect>
</mask>
</svg>

<svg width="256" height="192">
<image xlink:href="1.jpg" class="mask-image" width="256" height="192"></image>
</svg>
.mask-image {
mask: url(#mask);
mask-image: url(#mask);
}

这个例子中,IE浏览器和Chrome浏览器的遮罩效果生效,并不是因为它们支持mask-image属性,而是因为支持mask属性,这里逻辑生效的原理类似于直接在SVG的<image>元素上设置mask属性。

其他图片类型的遮罩

效果见 ​​https://demo.cssworld.cn/new/12/1-7.php​image-set()

.mask-image {
-webkit-mask-image: -webkit-image-set(url(bird.png) 1x, url(ellipse-rect.svg) 2x);
mask-image: image-set(url(bird.png) 1x, url(ellipse-rect.svg) 2x);
}

表示1倍屏中使用bird.png作为遮罩图像,2倍屏中使用ellipse-rect.svg作为遮罩图像。

cross-fade()

.mask-image {
-webkit-mask-image: -webkit-cross-fade(url(bird.png), url(ellipse-rect.svg), 50%);
mask-image: cross-fade(url(bird.png), url(ellipse-rect.svg), 50%);
}

表示ellipse-rect.svg保持50%的透明度进行遮罩渲染。
element()

.mask-image {
-webkit-mask-image: -webkit-element(#title);
mask-image: -moz-element(#title);
mask-image: element(#title);
}

表示把id属性值是title的元素作为遮罩图像进行处理。

mask-mode 遮罩模式

支持多属性

  • match-source【默认】——根据资源的类型自动采用合适的遮罩模式。例如,如果遮罩效果使用的是SVG中的<mask>元素,则此时的mask-mode属性的计算值是luminance,表示基于亮度判断是否要进行遮罩。如果是其他场景,则计算值是alpha,表示基于透明度判断是否要进行遮罩。
  • luminance——基于亮度判断是否要进行遮罩,可用于将jpg图片的白色部分变透明。因Chrome浏览器不支持mask-mode,可以使用非标准的mask-source-type属性代替(没有私有前缀)
.mask-image {
mask-mode: luminance;
mask-source-type: luminance;
}
  • alpha——基于透明度判断是否要进行遮罩。因Chrome浏览器不支持mask-mode,要实现此功能,可以使用
mask-type: alpha;

mask-repeat 遮罩重复

支持多属性,与background-repeat类似

mask-repeat: repeat-x;
mask-repeat: repeat-y;
mask-repeat: repeat;
mask-repeat: no-repeat;
mask-repeat: space;
mask-repeat: round;
mask-repeat: repeat space;
mask-repeat: repeat repeat;
mask-repeat: round space;
mask-repeat: no-repeat round;
  • ​repeat​​【默认值】,表示水平和垂直方向均平铺。
  • ​repeat-x​​表示水平方向平铺。
  • ​repeat-y​​表示垂直方向平铺。
  • ​no-repeat​​表示不平铺,会看到只有一个遮罩图形位于左上角。
  • ​space​​​与​​background​​​属性中的​​space​​的含义是类似的,表示遮罩图片尽可能地平铺,同时不进行任何剪裁。
  • ​round​​表示遮罩图片尽可能靠在一起,没有任何间隙,同时不进行任何剪裁。这意味着图片可能会产生缩放效果。

mask-position 遮罩定位

  • 支持多属性,与 background-position 类似
  • 默认计算值是0%0%,也就是相对左上角定位。
  • 单个关键字时(缺省关键字的解析为center)
mask-position: top;
mask-position: bottom;
mask-position: left;
mask-position: right;
mask-position: center;
mask-position: right top;
mask-position: 30% 50%;
mask-position: 10px 5rem;
mask-position: right 20px top 20px;
mask-position: 0 0, center;

mask-clip 遮罩裁剪

效果见 ​​https://demo.cssworld.cn/new/12/1-8.php​

用来设置遮罩效果显示的盒子区域,与background-clip类似

  • 【默认值】 border-box
  • 支持多属性
  • 不支持margin-box
mask-clip: border-box;
mask-clip: padding-box;
mask-clip: content-box;

mask-origin 遮罩起点

支持多属性,与background-origin类似

mask-origin: border-box; 【默认值】
mask-origin: content-box;
mask-origin: padding-box;
mask-origin: fill-box;
mask-origin: stroke-box;
mask-origin: view-box;

mask-size 遮罩尺寸

用于控制遮罩图片尺寸,与background-size类似

  • 支持多属性
  • 【默认值】auto
  • 垂直方向的尺寸值如果省略,会自动计算为auto
mask-size: cover;
mask-size: contain;
mask-size: 50%;
mask-size: 3em;
mask-size: 12px;
mask-size: 50% auto;
mask-size: 3em 25%;
mask-size: auto 6px;
mask-size: 50%, 25%, 25%;
mask-size: 6px, auto, contain;

mask-composite 遮罩合并

同时使用多张图片进行遮罩时的合成方式

Firefox浏览器支持的mask-composite属性的属性值

  • ​add​​【默认值】表示遮罩累加
  • ​subtract​​表示遮罩相减,也就是遮罩图片重合的区域不显示。这就意味着,遮罩图片越多,遮罩区域越小。
  • ​intersect​​表示遮罩相交,也就是遮罩图片重合的区域才显示遮罩。
  • ​exclude​​表示遮罩排除,也就是遮罩图片重合的区域被当作透明的。经常用于渐变图像,可以实现反向遮罩效果

代码中顺序越往后的图像层级越低

范例原图——两个遮罩

CSS遮罩【详解】_css_06


add 并集

CSS遮罩【详解】_前端_07


subtract 差集

CSS遮罩【详解】_前端_08


intersect 交集

CSS遮罩【详解】_php_09


exclude 非交集的部分

CSS遮罩【详解】_前端_10

经典应用——实现镂空的遮罩效果

CSS遮罩【详解】_前端_11


效果见 ​​https://demo.cssworld.cn/new/12/1-9.php​

<img src="1.jpg" class="mask-image" width="256" height="192">
.mask-image {
--mask: url(../images/bird.png) no-repeat center / contain,
linear-gradient(black, black);
-webkit-mask: var(--mask);
mask: var(--mask);
-webkit-mask-composite: xor;
mask-composite: exclude;
}

Chrome浏览器支持的mask-composite属性的属性值

-webkit-mask-composite: source-over;
-webkit-mask-composite: source-in;
-webkit-mask-composite: source-out;
-webkit-mask-composite: source-atop;
-webkit-mask-composite: destination-over;
-webkit-mask-composite: destination-in;
-webkit-mask-composite: destination-out;
-webkit-mask-composite: destination-atop;
-webkit-mask-composite: xor;
-webkit-mask-composite: copy;
-webkit-mask-composite: plus-lighter;
-webkit-mask-composite: clear;
  • ​source-over​​​表示遮罩区域累加,效果和CSS规范中的​​add​​值是一样的。
  • ​source-in​​​表示遮罩区域是交叉重叠的区域,效果和CSS规范中的​​intersect​​值是一样的。
  • ​source-out​​​表示遮罩区域是上层图像减去其和下层图像重叠的区域,效果和CSS规范中的​​subtract​​值是一样的。
  • ​source-atop​​表示保留底层图像区域,并在其上方累加上层和下层图像重叠的区域。
  • ​destination-over​​​表示下层遮罩图像叠加在上层遮罩图像上。不过,由于默认的遮罩模式是基于​​alpha​​​通道计算的,也就是基于透明度计算的,因此​​source-over​​​和​​destination-over​​​效果都是一样的,除非遮罩模式是基于亮度计算的,两者才会有明显的区别。​​destination-*​​​这几个值和上面​​source-*​​​几个属性值的区别就是,​​source-*​​​是上层图像对下层图像如何,而​​destination-*​​是下层图像对上层图像如何,大家可以理解为上下层图像的位置调换了。
  • ​destination-in​​表示遮罩区域是交叉重叠的区域。
  • ​destination-out​​表示遮罩区域是下层图像减去其和上层图像重叠的区域。
  • ​destination-atop​​表示保留上层图像区域,并在上方累加上层和下层图像重叠的区域。
  • ​xor​​​表示上层图像和下层图像重叠的区域透明,效果和CSS规范中的​​exclude​​属性值是一样的。
  • ​copy​​表示忽略下层图像,只使用上层图像区域作为遮罩区域。
  • ​plus-lighter​​​含义不详,规范文档中并没有任何相关的描述。我个人觉得应该表示自然光混合效果,适合用在​​mask-source-type​​​属性值为​​luminance​​的场景下。
  • ​clear​​含义不详。当遮罩图像有多张的时候,最终的遮罩效果是完全透明的。

边框遮罩 -webkit-mask-box-image

和border-image类似

使用范例——带小三角的渐变对话框

CSS遮罩【详解】_php_12

<ui-tips>感谢大家</ui-tips>
<ui-tips>感谢大家购买这本《CSS新世界》</ui-tips>
<ui-tips>感谢大家购买这本《CSS新世界》,如果你觉得这本书还不错,欢迎推荐给身边的朋友</ui-tips>
ui-tips {
display: inline-block;
padding: 12px 15px 24px;
color: #fff;
background: linear-gradient(45deg, deepskyblue, deeppink);
/* 应用边框遮罩效果 */
-webkit-mask-box-image: url("data:image/svg+xml,%3Csvg width='60' height='60'
viewBox='0 0 1024 1024' %3E%3Cpath d='M170.667 85.333h682.666c46.934 0 85.334 38.4 85.334
85.334v512c0 46.933-38.4 85.333-85.334 85.333H682.667L512 938.667 341.333
768H170.667c-46.934 0-85.334-38.4-85.334-85.333v- 512c0-46.934 38.4-85.334
85.334-85.334z'/%3E%3C/svg%3E") 10 10 20 40;
}

效果见 ​​https://demo.cssworld.cn/new/12/1-12.php​

  • SVG图像的宽高设置(也就是​​width='60' height='60'​​)是必须要进行的,否则SVG图像会随着容器尺寸的变化而发生变化,最终效果不能适应各种场景。
  • SVG图像的宽高尺寸要小,最好小于最小内容的宽高值,在本例中SVG图像的宽高都为60px,如果再大一些,例如100px,那么可能文字内容少的时候效果就会有瑕疵。
  • 只能实现小三角在一侧的效果,不能实现小三角居中定位的效果,因为在九宫格的边框剪裁分配中,中间区域的图像只能是拉伸或者平铺等方式,没有​​no-repeat​​类型。

># CSS遮罩的应用

1. png/svg图标变色

效果见 ​​https://demo.cssworld.cn/new/12/1-10.php​

.icon-delete {
display: inline-block;
width: 20px; height: 20px;
/* 背景色设为当前color的颜色 */
background-color: currentColor;
/* 小图标图像作为遮罩图像使用 */
--mask: url(delete.png) no-repeat center / 1.125em 1.125em;
-webkit-mask: var(--mask);
mask: var(--mask);
}

渐变色图标

CSS遮罩【详解】_css_13

.icon-delete {
background: linear-gradient(deepskyblue, deeppink);
mask: url(delete.png) no-repeat center;
}

注意事项:
应用遮罩的当前元素的outline效果会失去,这对于无障碍访问是有影响的,解决方法是将图标遮罩的执行放在伪元素中,也就是在.icon-delete::before{}语句中应用遮罩效果,这样,.icon-delete元素依然可以有outline轮廓效果。

2. 大尺寸PNG图片的尺寸优化

在性能要求较高的页面中可以发挥巨大的作用,比任何压缩软件都好用。

CSS遮罩【详解】_3c_14


CSS遮罩【详解】_3c_15


CSS遮罩【详解】_css_16


效果见 ​​https://demo.cssworld.cn/new/12/1-11.php​

由于遮罩图像的解析有跨域的限制,大小不足5KB的纯色的PNG背景遮罩图像可以直接转换为Base64格式并内联在CSS文件中

img {
--mask-img: url(data:image/png;base64,iVBORw0KG...==);
-webkit-mask-image: var(--mask-img);
mask-image: var(--mask-img);
}

这样做既节约了资源请求数,又没有跨域问题,相比直接使用URL地址连接,使用Base64格式内联是更好的做法。