奇妙的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);

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。