WebKit伪元素不遵循SVG遮罩,如何在WebKit浏览器实现兼容?
WebKit内核浏览器中SVG遮罩在伪元素存在时失效的修复方案
问题场景
我制作了如下SVG遮罩,可在中心位置裁剪出一个小圆洞:
<svg width="1" height="1" viewBox="0 0 1 1" style="position: absolute;pointer-events: none;top: -1px;left: -1px;width: 1px;height: 1px;"> <mask id="custom-mask" maskContentUnits="objectBoundingBox" viewBox="0 0 1 1"> <rect fill="white" x="0" y="0" width="1" height="1"></rect> <circle fill="black" cx="0.5" cy="0.5" r="0.2"></circle> </mask> </svg>
通过<foreignObject>应用此遮罩时,中间的洞可以正常显示:
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%"> <foreignObject x="0" y="0" width="100%" height="100%" mask="url(#custom-mask)" preserveAspectRatio="none"> <div class="block"> SOME CONTENT </div> </foreignObject> </svg>
但当.block类包含如下伪元素样式时,WebKit内核浏览器会丢失中间的裁剪洞,仅Firefox可以正常显示:
.block { background-color: red; width: 100%; height: 100%; } .block:after { content: ''; position: absolute; left: 0; top: 0; width: 100%; height: 100%; background-color: cyan; }
修复方案
WebKit内核中,<foreignObject>的遮罩仅作用于直接子元素的布局盒,绝对定位的伪元素会创建独立堆叠上下文,无法自动继承<foreignObject>的遮罩。我们可以将遮罩直接应用到.block及其伪元素上,确保两者都被裁剪:
修改后的SVG代码(移除<foreignObject>上的mask属性)
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%"> <foreignObject x="0" y="0" width="100%" height="100%" preserveAspectRatio="none"> <div class="block"> SOME CONTENT </div> </foreignObject> </svg>
修改后的CSS代码
.block { background-color: red; width: 100%; height: 100%; position: relative; /* 为绝对定位的伪元素提供定位基准 */ mask: url(#custom-mask); -webkit-mask: url(#custom-mask); /* 兼容WebKit内核浏览器 */ } .block:after { content: ''; position: absolute; left: 0; top: 0; width: 100%; height: 100%; background-color: cyan; mask: inherit; /* 继承父元素的遮罩规则 */ -webkit-mask: inherit; /* 兼容WebKit内核浏览器 */ }
原理说明
通过将遮罩直接绑定到.block元素,并让伪元素继承该遮罩,强制WebKit内核对伪元素也应用裁剪规则,从而实现和Firefox一致的显示效果。
内容的提问来源于stack exchange,提问作者alex smith
相关产品推荐
相关产品推荐

