奇妙的CSS属性MASK详解

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

奇妙的CSS属性MASK详解
本⽂将介绍 CSS 中⼀个⾮常有意思的属性 mask 。

顾名思义,mask 译为遮罩。

在 CSS 中,mask 属性允许使⽤者通过遮罩或者裁切特定区域的图⽚的⽅式来隐藏⼀个元素的部分或者全部可见区域。

其实 mask 的出现已经有⼀段时间了,只是没有特别多实⽤的场景,在实战中使⽤的⾮常少,本⽂将罗列⼀些使⽤ mask 创造出来的有意思的场景。

语法
最基本,使⽤ mask 的⽅式是借助图⽚,类似这样:
{
/* Image values */
mask: url(mask.png); /* 使⽤位图来做遮罩 */
mask: url(masks.svg#star); /* 使⽤ SVG 图形中的形状来做遮罩 */
}
当然,使⽤图⽚的⽅式后⽂会再讲。

借助图⽚的⽅式其实⽐较繁琐,因为我们⾸先还得准备相应的图⽚素材,除了图⽚,mask 还可以接受⼀个类似 background 的参数,也就是渐变。

类似如下使⽤⽅法:
{
mask: linear-gradient(#000, transparent) /* 使⽤渐变来做遮罩 */
}
那该具体怎么使⽤呢?⼀个⾮常简单的例⼦,上述我们创造了⼀个从⿊⾊到透明渐变⾊,我们将它运⽤到实际中,代码类似这样:
下⾯这样⼀张图⽚,叠加上⼀个从透明到⿊⾊的渐变,
{
background: url(image.png) ;
mask: linear-gradient(90deg, transparent, #fff);
}
应⽤了 mask 之后,就会变成这样:
这个 DEMO,可以先简单了解到 mask 的基本⽤法。

这⾥得到了使⽤ mask 最重要结论:图⽚与 mask ⽣成的渐变的 transparent 的重叠部分,将会变得透明。

值得注意的是,上⾯的渐变使⽤的是linear-gradient(90deg, transparent, #fff),这⾥的#fff纯⾊部分其实换成任意颜⾊都可以,不影响效果。

CodePen Demo -- 使⽤ MASK 的基本使⽤
使⽤ MASK 进⾏图⽚裁切
利⽤上述简单的运⽤,我们可以使⽤ mask 实现简单的图⽚裁剪。

使⽤ mask 实现图⽚切⾓遮罩
使⽤线性渐变,我们实现⼀个简单的切⾓图形:
.notching{
width: 200px;
height: 120px;
background:
linear-gradient(135deg, transparent 15px, deeppink 0)
top left,
linear-gradient(-135deg, transparent 15px, deeppink 0)
top right,
linear-gradient(-45deg, transparent 15px, deeppink 0)
bottom right,
linear-gradient(45deg, transparent 15px, deeppink 0)
bottom left;
background-size: 50% 50%;
background-repeat: no-repeat;
}
像是这样:
我们将上述渐变运⽤到 mask 之上,⽽ background 替换成⼀张图⽚,就可以得到运⽤了切⾓效果的图⽚:
background: url(image.png);
mask:
linear-gradient(135deg, transparent 15px, #fff 0)
top left,
linear-gradient(-135deg, transparent 15px, #fff 0)
top right,
linear-gradient(-45deg, transparent 15px, #fff 0)
bottom right,
linear-gradient(45deg, transparent 15px, #fff 0)
bottom left;
mask-size: 50% 50%;
mask-repeat: no-repeat;
得到的效果如下:
CodePen Demo -- 使⽤ MASK 实现图⽚切⾓遮罩
当然,实现上述效果还有其他很多种⽅式,譬如 clip-path,这⾥的 mask 也是⼀种⽅式。

多张图⽚下使⽤ mask
上述是单张图⽚使⽤ mask 的效果。

下⾯我们看看多张图⽚下,使⽤ mask 能碰撞出什么样的⽕花。

假设我们有两张图⽚,使⽤ mask,可以很好将他们叠加在⼀起进⾏展⽰。

最常见的⼀个⽤法:
div {
position: relative;
background: url(image1.jpg);
&::before {
position: absolute;
content: "";
top: 0;left: 0; right: 0;bottom: 0;
background: url(image2.jpg);
mask: linear-gradient(45deg, #000 50%, transparent 50%);
}
}
两张图⽚,⼀张完全重叠在另外⼀张之上,然后使⽤mask: linear-gradient(45deg, #000 50%, transparent 50%)分割两张图⽚:
CodePen Demo -- MASK 的基本使⽤,多张图⽚下的基本⽤法
当然,注意上⾯我们使⽤的 mask 的渐变,是完全的实⾊变化,没有过度效果。

我们稍微修改⼀下 mask 内的渐变:
{
- mask: linear-gradient(45deg, #000 50%, transparent 50%)
+ mask: linear-gradient(45deg, #000 40%, transparent 60%)
}
即可得到图⽚1向图⽚2过渡切换的效果:
CodePen Demo -- MASK 的基本使⽤,多张图⽚下的基本⽤法2
使⽤ MASK 进⾏转场动画
有了上⾯的铺垫。

运⽤上⾯的介绍的⼀些⽅法,我们就可以使⽤mask来进⾏⼀些图⽚切换间的转场动画。

使⽤线性渐变 mask:linear-gradient() 进⾏切换
还是上⾯的 Demo,我们通过动态的去改变 mask 的值来实现图⽚的显⽰/转场效果。

代码可能是这样:
div {
background: url(image1.jpg);
animation: maskMove 2s linear;
}
@keyframes {
0% {
mask: linear-gradient(45deg, #000 0%, transparent 5%, transparent 5%);
}
1% {
mask: linear-gradient(45deg, #000 1%, transparent 6%, transparent 6%);
}
...
100% {
mask: linear-gradient(45deg, #000 100%, transparent 105%, transparent 105%);
}
}
当然,像上⾯那样⼀个⼀个写,会⽐较费⼒,通常我们会借助 SASS/LESS 等预处理器进⾏操作。

像是这样:div {
position: relative;
background: url(image2.jpg) no-repeat;
&::before {
position: absolute;
content: "";
top: 0;left: 0; right: 0;bottom: 0;
background: url(image1.jpg);
animation: maskRotate 1.2s ease-in-out;
}
}
@keyframes maskRotate {
@for $i from 0 through 100 {
#{$i}% {
mask: linear-gradient(45deg, #000 #{$i + '%'}, transparent #{$i + 5 + '%'}, transparent 1%);
}
}
}
可以得到下⾯这样的效果(单张图⽚的显隐及两张图⽚下的切换):
CodePen Demo -- MASK linear-gradient 转场
使⽤⾓向渐变 mask: conic-gradient() 进⾏切换
当然,除了mask: linear-gradient(),使⽤径向渐变或者⾓向渐变也都是可以的。

使⽤⾓向渐变的原理也是⼀样的:@keyframes maskRotate {
@for $i from 0 through 100 {
#{$i}% {
mask: conic-gradient(#000 #{$i - 10 + '%'}, transparent #{$i + '%'}, transparent);
}
}
}
可以实现图⽚的⾓向渐显/切换:
CodePen Demo -- MASK conic-gradient 转场
这个技巧,在张鑫旭的这篇⽂章⾥,有更多丰富的例⼦,可以移步阅读:
你⽤的那些CSS转场动画可以换⼀换了
运⽤这个技巧,我们就可以实现很多有意思的图⽚效果。

像是这样:
mask 碰撞滤镜与混合模式
继续下⼀环节。

CSS 中很多有意思的属性,和滤镜和混合模式⼀结合,会碰撞出更多⽕花。

mask & 滤镜 filter: contrast()
⾸先,我们利⽤多重径向渐变,实现这样⼀张图。

{
background: radial-gradient(#000, transparent);
background-size: 20px 20px;
}
看着没什么特别,我们利⽤filter: contrast()对⽐度滤镜,改造⼀下。

代码⼤概是这样:
html,body {
width: 100%;
height: 100%;
filter: contrast(5);
}
div {
position: relative;
width: 100%;
height: 100%;
background: #fff;
&::before {
content: "";
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
background: radial-gradient(#000, transparent);
background-size: 20px 20px;
}
}
即可得到这样的图形,利⽤对⽐度滤镜,将图形变得⾮常的锐化。

这个时候,我们再叠加上不同的 mask 遮罩。

即可得到各种有意思的图形效果。

body {
filter: contrast(5);
}
div {
position: relative;
background: #fff;
&::before {
background: radial-gradient(#000, transparent);
background-size: 20px 20px;
+ mask: linear-gradient(-180deg, rgba(255, 255, 255, 1), rgba(255, 255, 255, .5));
}
}
CodePen Demo -- 使⽤ mask 搭配滤镜 contrast
我们叠加了⼀个线性渐变的 mask linear-gradient(-180deg, rgba(255, 255, 255, 1), rgba(255, 255, 255, .5)),注意,两个渐变颜⾊都是带透明度的。

或者换⼀个径向渐变:
{
mask: repeating-radial-gradient(circle at 35% 65%, #000, rgba(0, 0, 0, .5), #000 25%);
}
CodePen Demo -- 使⽤ mask 搭配滤镜 contrast
好的,下⼀步,与上⽂类似,我们添加上动画。

div {
...
&::before {
background: radial-gradient(#000, transparent);
background-size: 20px 20px;
mask: repeating-radial-gradient(circle at 35% 65%, #000, rgba(0, 0, 0, .5), #000 25%);
animation: maskMove 15s infinite linear;
}
}
@keyframes maskMove {
@for $i from 0 through 100 {
#{$i}% {
mask: repeating-radial-gradient(circle at 35% 65%, #000, rgba(0, 0, 0, .5), #000 #{$i + 10 + '%'});
看看,可以得到了⾮常酷炫的动画效果:
CodePen Demo -- 使⽤ mask 搭配滤镜 contrast 及动画
还记得使⽤filter: hue-rotate()⾊相滤镜吗。

再加上它,我们可以让颜⾊也变化起来。

CodePen Demo -- 使⽤ mask 搭配滤镜 contrast 及动画2
mask & 滤镜 filter: contrast() & 混合模式
接下来我们再叠加上混合模式。

注意到上⾯,其实我们的容器背景⾊是⽩⾊#fff。

我们可以通过多嵌套⼀层层级,再增加⼀个容器背景⾊,再叠加上混合模式,产⽣不⼀样的效果。

先不添加使⽤mask,重新构造⼀下结构,最终的伪代码带个是这样:
<div class="wrap">
<div class="inner"></div>
</div>
.wrap {
position: relative;
height: 100%;
background: linear-gradient(45deg, #f44336, #ff9800, #ffeb3b, #8bc34a, #00bcd4, #673ab7);
}
.inner {
height: 100%;
background: #000;
filter: contrast(700%);
mix-blend-mode: multiply;
&::before {
content: "";
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
background: radial-gradient(#fff, transparent);
background-size: 12px 12px;
}
}
原理⽰例图如下:
我们就可以得到如下的效果:
OK,到这⼀步,mask 还没有运⽤上,我们再添加上 mask。

.wrap {
background: linear-gradient(45deg, #f44336, #ff9800, #ffeb3b, #8bc34a, #00bcd4, #673ab7);
...
filter: contrast(700%);
mix-blend-mode: multiply;
&::before {
background: radial-gradient(#fff, transparent);
background-size: 12px 12px;
+ mask: linear-gradient(#000, rgba(0, 0, 0, .5));
}
}
CodePen Demo -- mask & filter & blend-mode
实际效果⽐截图好很多,可以点击 Demo 去看看。

当然,这⾥叠加的是mix-blend-mode: multiply,可以尝试其他混合模式,得到其他不⼀样的效果。

譬如,叠加mix-blend-mode: difference,等等等等:
更多有意思的叠加,感兴趣的同学需要⾃⼰多加尝试。

mask 与图⽚
当然,mask 最本质的作⽤应该还是作⽤于图⽚。

上⾯得到的重要结论:
图⽚与 mask ⽣成的渐变的 transparent 的重叠部分,将会变得透明。

也可以作⽤于 mask 属性传⼊的图⽚。

也就是说,mask 是可以传⼊图⽚素材的,并且遵循 background-image 与 mask 图⽚的透明重叠部分,将会变得透明。

运⽤这个技巧,可以制作⾮常酷炫的转场动画:
这⾥其实主要是在 mask 中运⽤了这样⼀张图⽚:
然后,使⽤了逐帧动画,快速切换每⼀帧的 mask :
.img1 {
background: url(image1.jpg) no-repeat left top;
}
.img2 {
mask: url(https:///AYJuRke.png);
mask-size: 3000% 100%;
animation: maskMove 2s steps(29) infinite;
}
.img2::before {
background: url(image2.jpg) no-repeat left top;
}
@keyframes maskMove {
from {
mask-position: 0 0;
}
to {
mask-position: 100% 0;
}
}
CodePen Demo -- mask 制作转场动画
当然,这个也是可以加上各种动画的。

上⾯已经演⽰了很多次了,感兴趣的同学可以⾃⼰尝试尝试。

最后
说了这么多,mask 其实还是属于⼀个⽐较冷门的属性。

在⽇常业务中能运⽤上的机会不多。

⽽且兼容性不算特别好,打开 MDN,可以看到,除了 mask 本⾝,还有很多与 mask 相关的属性,只是⽬前⼤部分还属于实验室阶段。

本⽂只是初略的介绍了 mask 本⾝,对 mask 相关的⼀些属性将会另起⼀⽂。

当然,即便如此,从属性本⾝⽽⾔,我觉得 mask 还是⾮常有意思的,带来了 CSS 更多可能性。

到此这篇关于奇妙的 CSS 属性 MASK详解的⽂章就介绍到这了,更多相关CSS 属性 MASK内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章,希望⼤家以后多多⽀持!。

相关文档
最新文档