如何为通过CSS mask显示的SVG添加drop-shadow阴影效果?
CSS mask场景下drop-shadow滤镜失效的解决办法
问题背景
我用两个SVG图标做表格列的筛选状态切换,为了让SVG颜色匹配动态文本色,改用了CSS mask实现。但之前用background-image时正常的hover阴影(drop-shadow),现在完全失效了。
问题原因
直接给带mask的元素加drop-shadow,滤镜会作用于元素的完整盒模型(这里是1em×1em的方块),而mask会裁剪掉方块的多余区域,导致阴影被一同裁掉,自然看不到效果。之前用background-image时,SVG本身是透明背景,滤镜会识别SVG的路径形状,所以阴影能正常显示。
解决方法
把mask和背景色放到伪元素里,让伪元素承载图标的视觉内容,再给伪元素加drop-shadow,这样滤镜会作用于mask裁剪后的实际图标形状:
修改后的CSS代码
/* Icon类用于筛选图标之外的其他图标 */ .icon{ display: inline-block; height: 1em; width: 1em; vertical-align: middle; position: relative; top: -.1em; margin-right: .1em; } .icon-filter, .icon-filter-active{ /* 原元素保持透明,不设置背景色 */ position: relative; } /* 用伪元素承载mask和背景色 */ .icon-filter::before, .icon-filter-active::before{ content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: var(--mainText); mask-size: cover; } .icon-filter::before{ mask-image: url("../../img/Filter Icon Empty.svg"); } .icon-filter-active::before{ mask-image: url("../../img/Filter Icon Full.svg"); } /* 给伪元素加hover阴影 */ .icon-filter:hover::before, .icon-filter-active:hover::before{ filter: drop-shadow(0 0 3px black); }
说明
- 原
.icon类去掉了background-size(因为现在用伪元素的mask-size) - 伪元素占满父元素的空间,承载mask和背景色,确保图标尺寸不变
- hover时给伪元素加
drop-shadow,滤镜会精准作用于mask裁剪后的SVG形状,阴影正常显示
内容的提问来源于stack exchange,提问作者VeryColdAir
相关产品推荐
相关产品推荐

