客栈说书:CSS遮罩CSS3 mask/masks详细介绍

这篇文章发布于 2017年11月6日,星期一,22:32,归类于 CSS相关。 阅读 103451 次, 今日 21 次 23 条评论

 

“客官,来来来,里面请,今天双11,优惠大酬宾,吃饭八折,还免费听书。”
张楚岚一听,心想这还挺划算的,大不了进去点碗青菜面,然后免费听场说书,稳赚不赔呀,果然是贫穷让我变得更有智慧。于是贼溜溜地进入了同福客栈。

座位尚多,或许是因为出于习惯性,张楚岚找了个靠门的位置坐了下来。刚坐下,小二就热情地把菜单递过来,客官,您看看你要点些什么?

张楚岚上下扫了一眼,背脊不禁微微一凉,以前也因为机缘巧合来过类似档次的客栈吃过饭,价格似乎没有这里这么贵呀,不禁瞟了瞟四周,怪不得还有这么多空座位呀,群众的眼睛是雪亮的呀。盯着后面价格来回扫视,终于确认了最便宜的菜是番茄鸡蛋汤:“那个,先给我来份番茄鸡蛋汤让我暖暖身子。”

然后合上菜单,递给了小二,小二似乎有些不确定,连忙问道:“就这些?”

“当然不是!”张楚岚的智慧又开启了,“我是广东福建那边过来的,吃饭之前都是先喝汤开胃,喝完汤以后才知道自己究竟想吃什么,到时候我再点其他菜。”

“这……好!”小二似乎又不能多问什么。转身欲离去,却被张楚岚叫住,“等下,问下,你们这里说书的内容是什么?什么时候开始?”

“客官,今天我们客栈说书内容讲的是马斯克(mask)的故事,12点开始!”

张楚岚抬头看看大厅悬挂的大钟,卧槽,这不已经11点60分了嘛,于是翘起了二郎腿,准备欣赏起来。

注意:本次说书时间很长,全部看完约半小时左右。

一、CSS mask遮罩的过往和现状

CSS mask遮罩属性的历史非常久远了,远到比CSS3 border-radius等属性还要久远,最早是出现在Safari浏览器上的,差不多可以追溯到09年。

不过那个时候,遮罩只能作为实验性的属性,做一些特效使用。毕竟那个年代还是IE浏览器的时代,属性虽好,但价值有限。

但是如今情况却大有变化,除了IE和Edge浏览器不支持,Firefox,Chrome以及移动端等都已经全线支持,其实际应用价值已不可同日而语。尤其Firefox浏览器,从版本55开始,已经全面支持了CSS3 mask属性。并且mask属性规范已经进入候选推荐规范之列,会说以后进入既定规范标准已经是板上钉钉的事情,大家可以放心学习,将来必有用处。

CSS mask属性兼容性截图

二、CSS mask属性面面观

在过去,CSS mask属性在使用的时候就是mask: xxx,但是现在随着这个属性的规范化,mask属性实际上已经成为了诸多mask-*的缩写,这和background, border性质是一样的。

具体是哪些属性的缩写呢,可以参见下面的列表:

下面对上面的这些属性,一个一个介绍。

三、CSS mask-image属性详细介绍

mask-image指遮罩使用的图片资源,默认值是none,也就是无遮罩图片。因此,和border属性中的border-style属性类似,是一个想要有效果就必须设定的属性值。

mask-image遮罩所支持的图片类型非常的广泛,可以是url()静态图片资源,格式包括JPG,PNG以及SVG等都是支持的;也可以是动态生成的图片,例如使用各种CSS3渐变绘制的图片。语法上支持CSS3各类渐变,以及url()功能符,image()功能符,甚至element()功能符。同时还支持多背景,因此理论上,使用mask-image我们可以遮罩出任意我们想要的图形,非常强大。

眼见为实,我们通过大量案例来展示mask-image的强大之处。

首先,下面所有案例使用原始图如下:

1. 最基础的png图片遮罩展示

我们使用的遮罩图片是一个名为loading.png的图片,如下:

loading效果

HTML如下:

<img src="ps1.jpg" class="mask-image">

CSS代码如下:

.mask-image {
    width: 250px; height: 187.5px;
    -webkit-mask-image: url(loading.png);
    mask-image: url(loading.png);
}

最后的效果,如下图所示:

PNG图片遮罩后的效果

眼见为实,您可以狠狠的点击这里:mask-image png图片效果示意demo

从上面这个最基本的案例,我们可以看出,所谓遮罩,就是原始图片只显示遮罩图片非透明的部分。例如本案例中,loading圆环有颜色部分就是外面一圈圆环,于是最终我们看到效果是原始图片,只露出了一个一个的圈圈环。并且半透明区域也准确遮罩显示了。

因此,我们很少使用jpg图片来作为遮罩图片的,因为jpg图片一定是完全不透明的,最终的效果就是原图什么也看不到。

除了图片使用外链地址,我们直接base64内嵌图片也是支持的,效果和上面一样。做了个demo,有兴趣可以狠狠地点击这里:mask-image base64格式png图片遮罩demo

另外,如果loading.png加载失败,则Firefox,Chrome浏览器下直接原始图不显示。

2. SVG图形遮罩效果展示

除了支持普通静态图片的遮罩,mask-image还支持SVG图形的遮罩效果。

假设有下面名为star.svg的SVG图形:

CSS代码如下:

.mask-image {
    width: 250px; height: 187.5px;
    -webkit-mask-image: url(star.svg);
    mask-image: url(star.svg);
}

结果原始图片显示为一片一片的星星形状:

SVG星星图形遮罩后的效果

眼见为实,您可以狠狠的点击这里:mask-image SVG图形遮罩效果demo

3. 使用SVG图形中<mask>元素作为遮罩元素

此用法和上面的区别在于仅仅是使用SVG中定义的<mask>作为遮罩,而不是SVG元素本身。

在定义上,我们既能够把内联SVG中的<mask>作为遮罩,也可以把外链的SVG文件中的<mask>作为遮罩;既能够作用在普通HTML上,也能够作用在SVG元素上。

单从最终的表现上来看,内联使用还是外链使用,应用在普通HTML上和应用在SVG原生上是有比较大的兼容性差异的,这里有必要好好说明下。


假设有如下SVG代码:

<svg width="50" height="50" version="1.1" xmlns="http://www.w3.org/2000/svg">
    <ellipse cx="25" cy="25" rx="20" ry="10" fill="#000000" stroke="none"></ellipse>
    <rect x="15" y="5" width="20" height="40" rx="5" ry="5" fill="#000000" stroke="none"></rect>
</svg>

则表现是下面这样的“姨妈巾”形状(效果实时):

下面我们要把上面的这个“姨妈巾”形状转化为我们需要的遮罩。

理论上,我们外面直接套个<mask>标签放在<defs>中就可以了,类似下面这样:

<svg>
    <defs>    
        <mask id="mask">
            <ellipse cx="25"  ...></ellipse>
            <rect x="15" ...></rect>
        </mask>
    </defs>    
</svg>

但是,注意,如果作为CSS mask属性值使用,上面这样直接处理是没有任何效果的,主要问题在于尺寸的识别上会有障碍。

通常的做法是设定<mask>元素的maskContentUnits属性值为objectBoundingBox,然后我们的<mask>元素内的图形尺寸全部限定在1px*1px的规则内。

于是,本案例需要的SVG <mask>相关代码理论上应该是下面这样:

<svg>
    <defs>    
        <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>
    </defs>    
</svg>

然而事情远没有这么简单:

  1. SVG <mask>其遮罩模式默认和普通图片的遮罩是不一样的,其遮罩类型是luminance,也就是基于亮度来进行遮罩的。而普通图片默认遮罩类型是alpha,基于透明度来遮罩的。当然,我们可以通过mask-typemask-mode来设置SVG <mask>遮罩类型是alpha,用法为:mask-type:alpha

    因此,上面代码两个形状的填充使用的是fill="white",白色亮度最高,表示完全遮罩。如果换成fill="black"则是完全透明。

  2. 假设上面的SVG代码内联在页面中,同时我们应用了如下CSS代码:
    .mask-image {
        mask-image: url(#mask);    /* #mask对应SVG中<mask>元素的id属性值 */
    }

    结果会发现,在Firefox浏览器下(目前仅Firefox浏览器支持任意元素的SVG <mask>遮罩),遮罩效果的边缘有些毛糙:

    遮罩后毛糙的边缘

    显然这样的遮罩效果是无法让我们满意的,好在我们是有办法可以让这个边缘变得更加平滑的,那就是重新构建一套同样形状,尺寸略大的,填充为黑色的图形,类似下面:

    <svg>
        <defs>    
            <mask id="mask" maskContentUnits="objectBoundingBox">
                <!-- 柔化边缘 -->
                <ellipse cx=".5" cy=".5" rx=".48" ry=".28" fill="black"></ellipse>
                <rect x=".2" y="0" width=".6" height="1" rx=".1" ry=".1" fill="black"></rect>
                <!-- 主体遮罩 -->
                <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>
        </defs>    
    </svg>

    此时,我们的图片遮罩边缘就变得异常平滑了,如下截图:
    遮罩边缘变得平滑了

  3. 当包含<mask>遮罩的SVG内联在页面中的时候,我们是不希望这个SVG占据任何尺寸的,需要把这个SVG隐藏掉。此时,是不能使用display:none或者使用visibility:hidden隐藏的,否则我们的遮罩效果就会失效。需要使用其他的方法隐藏,例如:
    svg {
        width: 0; height: 0;
        position: absolute;
    }

    或者(-150px仅示意不具代表性):

    svg {
        position: absolute;
        left: -150px; top: -150px;
    }

下面来看下不同调用方式和作用的不同元素上的兼容表现,SVG代码都是上面带“柔化边缘”注释的那段代码:

  1. 普通HTML元素内联SVG的<mask>

    HTML和CSS代码如下:

    <img src="ps1.jpg" class="mask-image">
    .mask-image {
        width: 250px; height: 187.5px;
        -webkit-mask-image: url(#mask);
        mask-image: url(#mask);
    }

    结果显示Chrome浏览器并不支持:
    Chrome浏览器不支持普通HTML元素的内联SVG遮罩

    Firefox浏览器表现符合预期:
    普通元素内联SVG遮罩Firefox截图

    眼见为实,您可以狠狠地点击这里:mask-image内联SVG的mask元素遮罩demo

  2. SVG元素内联SVG的<mask>

    HTML如下:

    <svg width="250" height="186">
        <image xlink:href="ps1.jpg" class="mask-image" width="250" height="186"></image>
    </svg>

    CSS如下:

    .mask-image {
        width: 250px; height: 187.5px;
        -webkit-mask-image: url(#mask);
        mask: url(#mask);
        mask-image: url(#mask);
    }

    结果所有浏览器,包括IE9浏览器都表现为预期的“姨妈巾”遮罩效果:

    IE9浏览器下SVG元素应用遮罩后效果截图

    眼见为实,您可以狠狠的点击这里:SVG <image>与内联SVG mask元素遮罩demo

    然而,然而,然而,重要转折说三遍,这里,包括IE9在内浏览器全部遮罩有效,并不是因为支持mask-image属性,除了Firefox浏览器,实际上目前其他所有浏览器都不支持SVG元素的<mask-image>遮罩;这里之所以其他浏览器都有效果起作用的,实际上是mask属性,生效原理类似于直接在SVG的<image>元素上设置mask属性,类似这样:

    <svg width="250" height="186">
        <image xlink:href="ps1.jpg" mask="url(#mask)" width="250" height="186"></image>
    </svg>

    因此,才有效果的。类似的CSS中的fill, stroke可以作用在SVG元素也是同样道理。

    mask-image是CSS特有,SVG本身并没有,因此,如果是下面CSS:

    .mask-image {
        width: 250px; height: 187.5px;
        -webkit-mask-image: url(#mask);
        mask-image: url(#mask);
    }

    则同样是仅Firefox浏览器支持。

  3. 普通HTML元素外链SVG文件的<mask>

    无论是clip-path还是这里的mask,外链SVG特性的支持一定是比内联SVG弱的。既然Chrome浏览器连普通HTML的内联SVG的<mask>都不支持,自然肯定不支持这里的外链SVG文件<mask>元素的遮罩支持。

    那之前表现良好的Firefox浏览器呢?

    比较幸运,Firefox浏览器最近支持了任意元素外链SVG文件的<mask>,为什么说最近呢?我看了下我现在的Firefox,显示最新版,版本是56,然后Firefox支持任意元素可以使用外链SVG <mask>元素作为遮罩是版本55开始了。

    至于上面的,任意元素内联SVG <mask>的支持,Firefox很早就已经支持。

    相信不久的版本,Chrome浏览器也会对其进行支持的,可以耐心等待。

  4. SVG元素外链SVG文件的<mask>

    经测试,目前这个也仅仅Firefox浏览器支持。

4. image()功能符资源作为遮罩元素

如下CSS:

.mask-image {
    width: 250px; height: 187.5px;
    -webkit-mask-image: image(url(loading.png), skyblue);
    mask-image: image(url(loading.png), skyblue);
}

由于目前Chrome和Firefox尚未支持image()功能符,因此,上面代码无法表现为预期的遮罩效果。不过我还是做了demo页面,因为说不定哪天就支持了,见:mask-image image()功能符与遮罩效果demo

5. image-set()功能符资源作为遮罩元素

相比image()功能符,image-set()功能符的兼容性要好很多,虽然目前Edge, Firefox都不支持,但Chrome/Safari/Android都可以无障碍使用,意味着移动端可以放心使用。CSS image-set()的主要作用是可以让不同屏幕密度设备加载不同的图片资源(之前有文章提及过)。

CSS使用示意如下:

.mask-image {
    width: 250px; height: 187.5px;
    -webkit-mask-image: -webkit-image-set(url(loading.png) 1x, url(star.svg) 2x);
    mask-image: image-set(url(loading.png) 1x, url(star.svg) 2x);
}

表示1倍屏幕密度(设备像素比为1)设备下使用loading.png作为遮罩图片,屏幕密度比2大的时候使用star.svg作为遮罩图片。

于是,普通PC显示器下,遮罩效果这样:
PNG图片遮罩后的效果

但是,如果是手机设备或者iMac, Mac pro之类设备,则会是下图所示效果:
retina屏幕下加载星星作为遮罩图片

眼见为实,您可以狠狠地点击这里:mask-image image-set()功能符与遮罩效果demo

6. cross-fade()功能符资源作为遮罩元素

图片透明叠加功能符cross-fade()我5年前就有介绍过,有兴趣可以点击这里进行了解。

目前兼容性和image-set()功能符类似,Chrome和移动端可以使用,Edge, Firefox尚不支持。

CSS使用示意如下:

.mask-image {
    width: 250px; height: 187.5px;
    -webkit-mask-image: -webkit-cross-fade(url(loading.png), url(star.svg), 50%);
    mask-image: cross-fade(url(loading.png), url(star.svg), 50%);
}

表示含义是star.svg这张图片保持为50%透明度。

因此,最终的遮罩效果如下图所示:

cross-fade()功能符遮罩效果截图

眼见为实,您可以狠狠地点击这里:mask-image cross-fade()功能符与图片遮罩demo

7. element()功能符资源作为遮罩元素

element()功能符可以让页面上的DOM元素作为图片显示,这个同样我之前介绍过,6年前,有兴趣可以点击这里进行了解。

虽然这么多年过去了,但是依然紧紧firefox浏览器支持element()功能符,并且需要-moz-私有前缀。

假设页面上有一段HTML如下:

<h4 id="title">作为图片的标题文字</h4>

CSS代码如下:

#title {
    width: -webkit-fit-content;
    width: -moz-fit-content;
    width: fit-content;
}
.mask-image {
    width: 250px; height: 187.5px;
    -webkit-mask-image: -webkit-element(#title);
    mask-image: -moz-element(#title);
    mask-image: element(#title);
}

则Firefox浏览器下的遮罩效果最终表现为:
element()功能符与元素作为遮罩图效果截图

眼见为实,您可以狠狠地点击这里(Firefox下有效果):mask-image element()功能符与遮罩demo

8. <gradient>渐变作为遮罩图片

这里的渐变可以是任意类型的CSS3渐变,例如可以是linear-gradient()线性渐变,也可以是repeating-linear-gradient()重复线性渐变,也可以是radial-gradient()径向渐变,也可以是repeating-radial-gradient()重复径向渐变,也可以是conic-gradient锥形渐变(只要浏览器支持)。

例如下面的CSS代码:

.mask-image {
    width: 250px; height: 187.5px;
    -webkit-mask-image: repeating-radial-gradient(rgba(0,0,0,0) 4px, rgba(0,0,0,1) 10px, rgba(0,0,0,1) 12px);
    mask-image: repeating-radial-gradient(rgba(0,0,0,0) 4px, rgba(0,0,0,1) 10px, rgba(0,0,0,1) 12px);
}

最终呈现为纹理遮罩:
重复径向渐变作为遮罩的效果截图

眼见为实,您可以狠狠地点击这里:mask-image重复径向渐变与遮罩demo

以上8种就是mask-image支持的遮罩图片用法。

四、CSS mask-mode属性详细介绍

mask-mode属性的默认值是match-source,意思是根据资源的类型自动采用合适的遮罩模式。

例如,如果我们的遮罩使用的是SVG中的<defs>中的<mask>元素,则此时的mask-mode属性的计算值是luminance,表示基于亮度遮罩。如果是其他场景,则计算值是alpha,表示基于透明度遮罩。

因此,mask-mode支持下面3个属性值:

mask-mode: alpha;
mask-mode: luminance;
mask-mode: match-source;

因为mask-image支持多图片,因此mask-mode也支持多属性值,例如:

mask-mode: alpha, match-source;

例如,我们把loading.png遮罩改成基于亮度luminance,如下CSS:

.mask-image {
    width: 250px; height: 187.5px;
    -webkit-mask-image: url(loading.png);
    mask-image: url(loading.png);
    -webkit-mask-mode: luminance;
    mask-mode: luminance;
}

结果Firefox浏览器下:
使用亮度模式遮罩后的效果截图

目前,mask-mode仅Firefox浏览器支持,因此,Chrome浏览器是看到的依然是基于alpha遮罩的效果,颜色不像上图那样淡。

眼见为实,您可以狠狠地点击这里:mask-mode:luminance与png图片遮罩demo

五、mask-repeat属性详细介绍

mask-repeat属性的默认值是repeat,行为类似于background-repeat属性。

支持以下一些单属性值:

mask-repeat: repeat-x;
mask-repeat: repeat-y;
mask-repeat: repeat;
mask-repeat: no-repeat;
mask-repeat: space;
mask-repeat: round;

同时,根据自己的测试,Chrome和Firefox浏览器都支持x轴y轴2两轴同时表示,例如:

mask-repeat: repeat space;
mask-repeat: repeat repeat;
mask-repeat: round space;
mask-repeat: no-repeat round;

由于mask-image支持多遮罩图片,因此,mask-repeat也支持多属性值,例如:

mask-repeat: space round, no-repeat;
mask-repeat: round repeat, space, repeat-x;

每个属性值的含义如下:

repeat-x
水平x平铺,效果类似:

repeat-x遮罩平铺效果截图

repeat-y
垂直y平铺。
repeat
默认值,水平和垂直平铺。
no-repeat
不平铺,会看到就一个遮罩图形孤零零的挂在左上角。

mask-repeat:no-repeat的效果截图

space
spacebackground等属性中的space,表示遮罩图片尽可能的平铺同时不发生任何剪裁。

然而根据我的测试,在Chrome浏览器下,一侧边缘还是发生了剪裁,不过不明显。Firefox浏览器则完美表现。

round
round表示遮罩图片尽可能靠在一起没有任何间隙,同时不发生任何剪裁。这就意味着图片可能会有比例的缩放。

关于每个属性值的具体表现,我特意做了一个demo,您可以狠狠的点击这里:mask-repeat不同属性值与遮罩效果demo

例如我们选择mask-repeatround,则遮罩效果就变成这样:
mask-repeat变成round效果截图

六、mask-position属性详细介绍

mask-positionbackground-position支持的属性值和表现基本上都是一模一样的。

例如,mask-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-image支持多遮罩图片,因此,mask-position也支持多属性值,例如:

mask-position: 0 0, center;

Chrome和Firefox浏览器都支持mask-position属性,Chrome还需要-webkit-私有前缀,Firefox浏览器现在已经不需要了。

为了直观体验不同mask-position属性值的遮罩效果,我特意做了个可交互的demo页面,您可以狠狠的点击这里:mask-position不同属性值与遮罩效果demo

例如,在mask-repeat值为no-repeat前提下,我们选择属性值为top,则遮罩效果表现为顶部居中:

mask-position顶部居中效果

七、mask-clip属性详细介绍

mask-clip属性性质上和background-clip类似,但是mask-clip支持的属性值要多一点,主要是多了个SVG元素的mask-clip支持。

支持属性值如下:

mask-clip: content-box;
mask-clip: padding-box;
mask-clip: border-box;
mask-clip: fill-box;
mask-clip: stroke-box;
mask-clip: view-box;

mask-clip: no-clip;

其中默认值是border-boxbackground-clip类似。同样也支持多属性值:

mask-clip: content-box, border-box;

虽然支持的属性值挺多,但是对于普通元素而言,生效的其实就前面3个,Firefox浏览器还支持no-clip,表示不对元素的遮罩效果做区域上的限制,言外之意就是只要是元素身上“长出来”的东西,都可以应用遮罩效果。

例如outline轮廓,又例如box-shadow盒阴影,都是可以应用遮罩效果的。

做了个demo,演示不同mask-clip属性值的不同表现,您可以狠狠的点击这里:mask-clip不同属性值与遮罩效果demo

例如,已知CSS如下:

.mask-image {
    width: 250px; height: 187.5px;
    -webkit-mask-image: url(loading.png);
    mask-image: url(loading.png);
    border: 20px solid #34538b;
    padding: 20px;
    margin: 20px;
}

则我们选择content-box效果:
mask-clip content-box效果截图

fill-boxstroke-boxview-box要与SVG元素关联才有效果,目前还没有任何浏览器对其进行支持 更新于2020-07-26 Firefox浏览器支持了这3个关键字,反而是Chrome浏览器迟迟未支持。

八、mask-origin属性详细介绍

mask-origin属性性质上和background-origin类似,但是mask-origin支持的属性值要多一点,主要是多了个SVG元素的mask-origin支持。

支持属性值如下:

mask-origin: content-box;
mask-origin: padding-box;
mask-origin: border-box;
mask-origin: fill-box;
mask-origin: stroke-box;
mask-origin: view-box;

其中默认值是border-boxbackground-origin类似。同样也支持多属性值:

mask-origin: content-box, border-box;

虽然支持的属性值挺多,但是对于普通元素而言,目前生效的其实就前面3个。

做了个demo,演示不同mask-origin属性值的不同表现,您可以狠狠的点击这里:mask-clip不同属性值与遮罩效果demo

例如,已知CSS如下:

.mask-image {
    width: 250px; height: 187.5px;
    -webkit-mask-image: url(loading.png);
    mask-image: url(loading.png);
    border: 20px solid #34538b;
    padding: 20px;
    margin: 20px;
}

则我们选择content-box效果:
mask-origin选择content-box效果截图

fill-boxstroke-boxview-box要与SVG元素关联才有效果,目前还没有任何浏览器对其进行支持。

九、mask-size属性详细介绍

mask-size属性性质上和background-size类似,支持的属性值也类似,作用是控制遮罩图片尺寸。

默认值是auto.

支持containcover这两个关键字:

mask-size: cover;
mask-size: contain;

支持各类数值(缺省高度会自动计算为auto):

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;

效果演示,如下CSS:

.mask-image {
    width: 250px; height: 187.5px;
    -webkit-mask-image: url(star.svg);
    mask-image: url(star.svg);
    -webkit-mask-size: cover;
    mask-image: cover;
}

结果效果如下图(Chrome和Firefox浏览器均如此):
mask-size:cover遮罩效果截图

眼见为实,您可以点击这里:mask-size:cover与图片遮罩效果demo

十、mask-type属性简介

mask-type属性功能上和mask-mode类似,都是设置不同的遮罩模式。但还是有个很大的区别,那就是mask-type只能作用在SVG元素上,本质上是由SVG属性演变而来,因此,Chrome等浏览器都是支持的。但是mask-mode是一个针对所有元素的CSS3属性,Chrome等浏览器并不支持,目前仅Firefox浏览器支持。

由于只能作用在SVG元素上,因此默认值表现为SVG元素默认遮罩模式,也就是默认值是luminance,亮度遮罩模式。如果需要支持透明度遮罩模式,可以这么设置:

mask-type: alpha;

十一、mask-composite属性详细介绍

mask-composite表示当同时使用多个图片进行遮罩时候的混合方式。支持属性值包括:

mask-composite: add;
mask-composite: subtract;
mask-composite: intersect;
mask-composite: exclude;

以上属性值,目前仅Firefox浏览器支持,Chrome默认mask-composite计算值是source-over,和标准默认值add有些差异,作用是一样的,表示多个图片遮罩效果是累加。

各属性值释义如下:

add
遮罩累加。
subtract
遮罩相减。也就是遮罩图片重合的地方不显示。意味着遮罩图片越多,遮罩区域越小。
intersect
遮罩相交。也就是遮罩图片重合的地方才显示遮罩,。
exclude
遮罩排除。也就是后面遮罩图片重合的地方排除,当作透明处理。

为了演示不同mask-composite属性值的不同表现,特意做了个可交互的demo,您可以狠狠的点击这里:mask-composite不同属性值与遮罩效果demo

demo使用CSS代码:

.mask-image {
    width: 250px; height: 187.5px;
    -webkit-mask-image: url(loading.png), url(star.svg);
    mask-image: url(loading.png), url(star.svg);
}

例如,Firefox浏览器下,选择mask-composite:subtract,则效果如下截图所示:
mask-composite:subtract遮罩效果截图

更新于2019-03-21
Chrome浏览器mask-composite支持的属性值有变化,如下:

mask-composite:source-over;
mask-composite:source-in;
mask-composite:source-out;
mask-composite:source-atop;
mask-composite:destination-over;
mask-composite:destination-in;
mask-composite:destination-out;
mask-composite:destination-atop;
mask-composite:plus-lighter;
mask-composite:copy;
mask-composite:clear;
mask-composite:xor;

示意图:
Chrome浏览器mask-composite支持的属性值

借鉴了Canvas中的globalCompositeOperation属性值,各个属性值详细作用可以点击这里

简单描述下属性值作用:

source-over
遮罩累加。
source-in
重叠的位置是遮罩,不重叠的位置表现为透明。
source-out
重叠的位置是不遮罩,表现为透明。
source-atop
略。参见这个链接。剩余几个属性值也略,内容太多,这里不方便展开……
略...
略...

十二、说书结束

终于说书结束了,张楚岚意犹未尽,番茄鸡蛋汤也都忘记吃已经凉了,连忙狼吞虎咽吃完,然后让小二买单。

小二过来一看,略有不悦:“客官,你就不再点的什么?”

“不是我不想点,这汤凉了,我喝下去就没有吃其他东西的胃口了。就这样买单吧~”张楚岚嘿嘿一笑。

“这……,小二犹豫了下,我去问问老板娘……”

“咦?”张楚岚觉得有些不对劲,想撤。正起身,突然门外蹿出五大三黑数人将张楚岚团团围住。“小子,你吃这么点东西也想走,你听了完整的说书可是有至少100元的最低消费,快交钱,不然可别怪我拳头不长眼睛”。

气氛顿时异常紧张,张楚岚琢磨,自己身上总共43元8角,压根不够吃饭费用。看来只能强突了。于是指着说书方向大叫:“老板娘,是我啊!”众人不禁转头望去,张楚岚立马发动雷诀,闪到门外。本以为已经逃走,突然看到两指直逼自己胸前,同时传来声音“葵花点穴手”,眼看即将击中,张楚岚一运力,使出雷诀三阶雷步,一个半转身,手指擦着衣服而过,好险。定睛一看,原来是刚才的小二,从刚才过招可以看出此人武功不菲,看来此客栈是藏龙卧虎之地不宜久留。于是,张楚岚一摸口袋,扔向小二,同时叫道,这是你们要的100元。小二下意识拿手去接住,再回头,张楚岚已使用雷诀逃到没影子了。

“吭,算你跑得快!”小二冷吭到。然后张开手看接住的钱,一口老血吐出来,只有10块钱,拳头紧握,低声怒吼道,“小子,下次再遇到我盗神,必要你吃不了兜着走!”


至此本文全部结束,希望本文的内容能够对您的学习有所帮助。另外,行文匆忙,有错误在所难免,欢迎纠正。

本文有参考MDN文档:CSS/mask

感谢花这么多时间阅读!

(本篇完)

分享到:


发表评论(目前23 条评论)

  1. 莫弈说道:

    鑫哥 写小说吧
    我表示小说那段意犹未尽 哈哈

  2. falleg说道:

    鑫哥,我在做学校的项目时。有一个场景是把一张图片在另一个自定义矩形盒子上镂空。看了很多关于mask和混合模式相关的,一直没找到合适的方式做。比如现在矩形盒子里面有一张背景图片,然后再有一个小五角星图片,最终要实现在这个背景图上扣掉这个五角星的形状,而不是呈现这个五角星形状。

  3. 无须说道:

    厉害

  4. 风清云淡说道:

    小白:蒙版本的大小可调么?

  5. 曾亦说道:

    本机调试的时候img图片上mask使用svg图片遮挡,在Firefox上为什么会遮挡全部(图片也不显示)(使用的是你这个https://www.zhangxinxu.com/study/201711/mask-image-svg-url.html),其他浏览器是正常。当把demo放在GitHub使用page访问的时候,Firefox访问也能正常显示,请问您有没有遇到这样的问题

  6. 这个标签可以被平铺吗?说道:

    这个标签可以被平铺吗?有个需求需要用小球进行填充,然后整体有需要有渐变效果

  7. meiiew说道:

    mask-size栏目中的.mask-image {
    width: 250px; height: 187.5px;
    -webkit-mask-image: url(star.svg);
    mask-image: url(star.svg);
    -webkit-mask-size: cover;
    mask-image: cover;
    }
    其中 mask-image: cover;笔误了

  8. yaohou说道:

    “因此,我们很少使用jpg图片来作为遮罩图片的,因为jpg图片一定是完全不透明的,最终的效果就是原图什么也看不到。”这句话说反了,效果应该是完全看到了原图

  9. test007说道:

    “因此,我们很少使用jpg图片来作为遮罩图片的,因为jpg图片一定是完全不透明的,最终的效果就是原图什么也看不到。”

    应该是最终效果是 遮罩图 什么也看不到, 看到的全是原图吧?

  10. nikolausliu说道:

    不摇碧莲的名分这次算是坐实了

  11. family说道:

    background-origin的默认值应该是padding-box~~

  12. 紫英说道:

    张宝宝

  13. 新闻头条说道:

    文章不错非常喜欢

  14. 林小雨说道:

    作者好厉害, 好多次遇到问题在百度搜索都找到这来了

  15. 盖大楼说道:

    一个被前端耽误的小说家。