前言
CSS3的mask是一个大概念,包括若干个属性,MDN文档:https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_Masking
顾名思义,mask意思是遮罩。在CSS中,mask属性允许使用者通过遮罩或者裁切特定区域的图片的方式来隐藏一个元素的部分或者全部可见区域。
其实mask的出现已经有一段时间了,只是没有特别多实用的场景,在实战中使用的非常少,本文将罗列一些使用 mask 创造出来的有意思的场景,实现五毛钱特效。我们的原则是,代码能实现的,一定不借助图片。
由于Chrome浏览器只支持带前缀的写法,本文也都带上前缀,避免调试的时候看不到效果。真正开发的时候脚手架通常自动加前缀,所以不用担心。
mask值为渐变的若干种应用
mask值可以是渐变,通常与背景图合用。
基础应用
原图:
加mask:
<style>
.xxclass {
width: 600px;
height: 329px;
background: url(wow.jpg) top left no-repeat;
background-size: cover;
-webkit-mask: linear-gradient(to right, transparent, #000);
}
</style>
<div class="xxclass">
<!-- <img src="wow.jpg" /> -->
</div>
注意2点:
transparent部分会变成白色的半透明遮罩。无论渐变到右边是什么颜色,transparent部分都是白色半透明。
右边的部分尽管设定了#000颜色,但反而是透明的,而且无论你设任何颜色,都是透明的。
总之:
mask效果跟背景设置半透明效果是完全相反的,所以要反着理解!而且,你无需纠结色值,因为什么色值都一样结果,你只需要记得给某个部分设置transparent
即可。所以,如果从某一色值渐变到另一色值,可想而知,什么效果也没有。
进阶应用,裁剪容器
我们现在已经得出了结论:mask“全透明”意味着全白,“半透明”意味着半白,“有色值”意味着透明。有就是无,无就是有。
所以,我们可以给容器某些部位设置“全透明”,就会让这些部位显示为白色,这样等同于对容器进行了裁剪。有一个前提是,容器周围必须是#fff白色,否则裁剪部位跟周围又有色差,看起来会非常奇怪。
先拿一个容器测试一下,给背景设四角透明,调试好了再搬迁到mask上,记得“有就是无,无就是有”即可。
.cut {
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上:
.cut {
width: 200px;
height: 120px;
background: url(image.png);
-webkit-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;
-webkit-mask-size: 50% 50%;
-webkit-mask-repeat: no-repeat;
}
注意:clip-path
也能实现这个效果,这就是另外的知识了。
进阶应用,叠加背景图,形成拼图效果
原理是:容器先设背景图a.png,然后设::before
与容器位置叠加,设背景图b.png和mask。b.png会压在a.png上方。
.aa {
position: relative;
width: 510px;
height: 302px;
background: url(a.png) no-repeat;
background-size: cover;
}
.aa::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 510px;
height: 302px;
background: url(b.png) no-repeat;
background-size: cover;
-webkit-mask: linear-gradient(75deg, #000 50%, transparent 50%);
}
现在的问题是过度不平滑,我们改改:
/* -webkit-mask: linear-gradient(75deg, #000 50%, transparent 50%); */
-webkit-mask: linear-gradient(75deg, #000 40%, transparent 60%);
这时候:
看看,现在无需PS,我们就做出一个非常有感觉的、完全不亚于PS的拼图效果。
进阶应用,动画效果
我们要做的动画是分界线2秒钟从左下角滚到右上角。
先用Sass搞一个keyframes:
@keyframes ani {
@for $i from 0 through 100 {
#{$i}% {
-webkit-mask: linear-gradient(75deg, #000 #{$i + '%'}, transparent #{5 + $i + '%'}, transparent #{5 + $i + '%'});
}
}
}
然后给::before加上:
animation: ani 2s linear;
animation-fill-mode: forwards;
进阶应用,圆锥渐变
会以12点钟开始,顺时针扫过整个容器。
@keyframes ani {
@for $i from 0 through 100 {
#{$i}% {
-webkit-mask: conic-gradient(#000 #{$i + '%'}, transparent #{$i + '%'}, transparent);
}
}
}