在常见的场景中,一张图片只能方形或者圆形展示,如果想要以不规则的通常都是通知 UI 小姐姐让她帮忙处理一下图片,然后直接用就好了;
但是小姐姐只会影响我敲代码的速度,等她处理图片我的代码都写好了,接下来我就带大家一起来看看各种遮罩处理方式。
所有场景的效果:
代码片段
渐变背景
我们可以通过叠加渐变背景来实现遮罩效果,这种方式比较简单,但是需要注意的是渐变的方向和颜色,如果不合理会导致遮罩效果不理想。
/* 格子模糊效果 */
.container {
background: repeating-linear-gradient(transparent, transparent 5px, #fff 5px, #fff 10px),
repeating-linear-gradient(90deg, transparent, transparent 5px, #fff 5px, #fff 10px),
url("https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a153dac6e9174818800b6dfa81413cf8~tplv-k3u1fbpfcp-watermark.image?");
background-size: 100% 100%;
width: 500px;
height: 600px;
filter: blur(1px);
}
/* 径向渐变 */
.container {
background: repeating-radial-gradient(circle at 50% 50%, #fff 0, #fff 10px, transparent 10px, transparent 20px),
url("https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a153dac6e9174818800b6dfa81413cf8~tplv-k3u1fbpfcp-watermark.image?");
background-size: 100% 100%;
width: 500px;
height: 600px;
filter: blur(1px);
}
用径向渐变的效果并不好,因为渐变就相当于一个图像的图层,你只能在上一个图层的基础上进行处理,而径向渐变的效果是从中心向外扩散的,然后应用在整个图片上,如果没有很好的创意,这种效果并不好看。
同时使用渐变背景,上面的透明只是图层的透明,而不是整个 dom 的透明,所以下面介绍 clip-path
的方式。
clip-path
clip-path
是 CSS3 新增的属性,可以用来裁剪元素的显示区域,可以用来实现遮罩效果。
/* 圆形遮罩 */
.container {
background: url("https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a153dac6e9174818800b6dfa81413cf8~tplv-k3u1fbpfcp-watermark.image?");
background-size: 100% 100%;
width: 500px;
height: 600px;
clip-path: circle(50% at 50% 50%);
}
上面只是一个简单的示例,先来详解一下 clip-path
的语法:
clip-path: < shape > | < url > | none ;
- shape:形状,可以是
inset()
、circle()
、ellipse()
、polygon()
、path()
等,具体可以参考 MDN。 - url:引用一个 svg 的路径,可以通过
clip-path: url(#clip)
来引用一个 id 为clip
的 svg。
clip-path
的效果是裁剪元素的显示区域,最关键的是裁剪区域可以是不规则的,这样用它来实现遮罩效果就很方便了,不过说它是遮罩好像有点勉强,不过没关系,能达到我们要的效果就行。
来演示一下 clip-path
的效果:
.container {
background: url("https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a153dac6e9174818800b6dfa81413cf8~tplv-k3u1fbpfcp-watermark.image?");
background-size: 100% 100%;
width: 500px;
height: 600px;
clip-path: path('m254.02022,200.61348c82.25288,-239.21342 404.52235,0 0,307.56012c-404.52235,-307.56012 -82.25288,-546.77354 0,-307.56012z');
}
上面的效果是用 path()
来实现的,path
其实就是svg
的路径,而且上面也提到了可以使用url()
来引用一个 svg
,所以我们可以使用 svg
来实现。
.container {
background: url("https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a153dac6e9174818800b6dfa81413cf8~tplv-k3u1fbpfcp-watermark.image?");
background-size: 100% 100%;
width: 500px;
height: 600px;
clip-path: url(#love);
}
<svg width="0" height="0" version="1.1" xmlns="http://www.w3.org/2000/svg">
<defs>
<clipPath id="love">
<path d="m254.02022,200.61348c82.25288,-239.21342 404.52235,0 0,307.56012c-404.52235,-307.56012 -82.25288,-546.77354 0,-307.56012z"/>
</clipPath>
</defs>
</svg>
都用上了svg
了,那么iconfont
也就用上呀~~~
.container {
background: url("https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a153dac6e9174818800b6dfa81413cf8~tplv-k3u1fbpfcp-watermark.image?");
background-size: 100% 100%;
width: 500px;
height: 600px;
clip-path: url(#medicalCare);
}
<svg>
<defs>
<clipPath id="medicalCare">
<path stroke="null" id="svg_1" p-id="1314" fill="#03AD82"
d="m499.0635,539.46077c0.10317,1.08126 0.15849,2.18038 0.15849,3.29379l0,28.56709c0,15.77689 -11.13094,28.56709 -24.8611,28.56709l-447.49978,0c-13.73016,0 -24.8611,-12.7902 -24.8611,-28.56709l0,-28.56709c0,-1.11412 0.05594,-2.21252 0.16346,-3.29307c3.5657,-61.01788 66.98512,-112.79931 155.75478,-134.43317l92.69274,176.29181l92.69336,-176.29181c88.76966,21.63386 152.18908,73.41529 155.75914,134.43245zm-247.20944,-358.79412c64.71779,0 120.0443,15.77618 142.35962,38.06279c0.45807,0.03142 0.91986,0.09284 1.37979,0.18569c10.81706,2.19252 16.97702,20.97325 13.75875,41.94863c-3.13685,20.43975 -14.02166,35.42105 -24.58514,34.14482c-16.31634,59.68094 -70.19966,103.48215 -134.15608,103.48215c-62.45667,0 -115.30764,-41.77223 -132.94908,-99.31064c-10.78412,2.07111 -22.09779,-13.12515 -25.30611,-34.03055c-3.14742,-20.5126 2.67319,-38.92552 13.04773,-41.77937c18.91308,-24.70482 77.32485,-42.70352 146.45052,-42.70352z"/>
<path stroke="null" id="svg_2" p-id="1315" opacity="0.7" fill="#7EDEC6"
d="m246.22388,21.09091c62.47625,0 120.90583,14.8742 170.74232,40.72034l0.00129,146.03052c-44.74378,-31.81112 -104.62427,-51.2555 -170.42076,-51.2555c-65.84685,0 -125.76931,19.47387 -170.52342,51.32883l0.00323,-146.3852c49.71639,-25.67318 107.94774,-40.43899 170.1967,-40.43899l0.00065,0zm8.01971,21.51985l-15.49702,0a5.16567,6.37625 0 0 0 -5.16567,6.37625l0,25.50501l-20.6627,0a5.16567,6.37625 0 0 0 -5.16567,6.37625l0,19.12876a5.16567,6.37625 0 0 0 5.16567,6.37625l20.6627,0l0,25.50501a5.16567,6.37625 0 0 0 5.16567,6.37625l15.49702,0a5.16567,6.37625 0 0 0 5.16567,-6.37625l0,-25.50501l20.6627,0a5.16567,6.37625 0 0 0 5.16567,-6.37625l0,-19.12876a5.16567,6.37625 0 0 0 -5.16567,-6.37625l-20.6627,0l0,-25.50501a5.16567,6.37625 0 0 0 -5.16567,-6.37625z"/>
</clipPath>
</defs>
</svg>
iconfont
的svg
代码分辨率是1024*1024
,使用clip-path
的时候,是按照svg
的分辨率来裁剪的,只能通过修改path
来修改大小,我这里使用在这个网站上修改了大小。
mask
mask
是css3
新增的属性,它的作用是将一个元素的部分或全部区域隐藏起来,只显示另一个元素的部分或全部区域。
mask
才是正儿八经的遮罩,它是一个聚合属性,包含如下属性:
- mask-image:指定遮罩图像
- mask-mode:指定遮罩图像的混合模式
- mask-repeat:指定遮罩图像的重复方式
- mask-position:指定遮罩图像的位置
- mask-size:指定遮罩图像的大小
- mask-origin:指定遮罩图像的原点
- mask-clip:指定遮罩图像的裁剪区域
- mask-composite:指定遮罩图像的合成方式
我们直接上效果代码:
.container {
background: url("https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a153dac6e9174818800b6dfa81413cf8~tplv-k3u1fbpfcp-watermark.image?");
background-size: 100% 100%;
width: 500px;
height: 600px;
-webkit-mask-image: linear-gradient(transparent 50%, #000 50%);
}
mask
属性需要带上兼容性前缀-webkit-
,通常我们使用的时候设置的都是mask-image
,其他的属性默认即可。
这个属性结合了渐变
和clip-path
的特性,可以实现很多有趣的效果,比如:
.container {
background: url("https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a153dac6e9174818800b6dfa81413cf8~tplv-k3u1fbpfcp-watermark.image?");
background-size: 100% 100%;
width: 500px;
height: 600px;
-webkit-mask-image: radial-gradient(#fff, transparent), url(love.svg) ;
}
可以看到上面的效果是两种叠加的效果,这个叠加效果我们可以通过mask-composite
来修改:
add
:默认值,将两个图层的颜色相加subtract
:将第二个图层的颜色从第一个图层中减去intersect
:将两个图层的颜色相乘exclude
:将两个图层的颜色相减
mask-composite
在规范上只有这么些属性,在-webkit-mask-composite
会有更多的属性,比如destination-out
,destination-in
等等,这些属性效果大家可以自己去尝试,MDN上也有介绍。
结束
目前个人已知的可以达到此裁剪元素,遮挡或者叠加元素原本的内容或背景的属性就这些了,如果有遗漏的,欢迎大家补充。