应用CSS mask-image后元素边框消失的原因及纯CSS解决方案
为什么用SVG做mask-image后元素边框消失了?纯CSS解决方案
嘿,这个问题我之前也碰到过!咱们先搞清楚原因,再给你靠谱的纯CSS解决办法。
问题根源
CSS的mask(包括mask-image)属性会对元素的所有视觉内容生效——不管是背景色、边框,还是文本,都会被mask的形状裁剪。你的SVG mask是一个居中的心形,而元素的边框是在盒子的边缘区域,大部分都处于mask的透明区域(也就是心形之外的部分),所以这部分边框直接被隐藏了;就算是心形覆盖到的边框区域,也会因为mask的裁剪,和背景一起只显示心形的形状,但因为边框在盒子边缘、心形在中间,最终看起来边框就完全消失了。
纯CSS解决方案
方法1:用渐变背景模拟边框(推荐)
这种方法不需要额外元素或伪元素,直接通过多层背景渐变模拟边框,配合透明边框占位,让mask同时作用于边框和背景:
.icon { padding: 5px; width: 150px; height: 150px; display: inline-block; /* 透明边框占位,给渐变边框留出空间 */ border: 5px solid transparent; /* 第一层渐变模拟边框(填充到padding边缘),第二层是背景色(填充内容区域) */ background: linear-gradient(#000, #000) padding-box, red content-box; /* 保留原有的mask设置 */ -webkit-mask: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/18515/heart.svg) no-repeat 50% 50%; -webkit-mask-size: contain; mask: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/18515/heart.svg) no-repeat 50% 50%; mask-size: contain; } .icon.blue { /* 蓝色元素替换背景色层 */ background: linear-gradient(#000, #000) padding-box, blue content-box; }
原理:padding-box让渐变只填充到padding的边缘(正好是我们想要的边框位置),content-box让背景色填充内容区域,再加上透明的border占位,整个元素的视觉区域(包括模拟的边框)都会被mask裁剪成心形,边框就能和背景一起正常显示了。
方法2:用伪元素单独处理边框
如果不想用渐变,也可以用伪元素生成边框层,然后给伪元素应用相同的mask:
.icon { padding: 5px; width: 150px; height: 150px; display: inline-block; position: relative; /* 给元素本身应用mask */ -webkit-mask: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/18515/heart.svg) no-repeat 50% 50%; -webkit-mask-size: contain; mask: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/18515/heart.svg) no-repeat 50% 50%; mask-size: contain; } /* 伪元素模拟边框 */ .icon::before { content: ''; position: absolute; inset: 0; /* 等同于top/right/bottom/left: 0,铺满父元素 */ border: 5px solid #000; /* 继承父元素的mask设置,保证形状一致 */ -webkit-mask: inherit; mask: inherit; z-index: -1; /* 把边框层放在背景下方,避免遮挡内容 */ } .icon.red { background-color: red; } .icon.blue { background-color: blue; }
原理:伪元素会铺满整个父元素,设置边框后应用和父元素相同的mask,这样边框就会被裁剪成心形,同时父元素的背景也被mask处理,最终就能看到带心形边框的彩色背景了。
内容的提问来源于stack exchange,提问作者Sakis
相关产品推荐
相关产品推荐

