Safari 中的 SVG 不受欢迎的 alpha 蒙版行为

SVG undesired alpha mask behavior in Safari

我正在尝试将单个遮罩应用于两个重叠的 <rect> SVG 元素。 I've created a simplified live example 使用以下代码:

<svg viewBox="0 0 100 100" style="background: #000">
 <defs>
  <!--  Define radial gradient  -->
  <radialGradient id="radialFill">
   <stop stop-color="white" offset="0.8"/>
   <stop stop-color="black" offset="1"/>
  </radialGradient>
  
  <!--  Define mask with gradient  -->
  <mask id="SVGMask" mask-type="luminance">
   <circle fill="url(#radialFill)" cx="50" cy="50" r="50"/>
  </mask>
 </defs>
 
 <!--  Use mask on group  -->
 <g id="combined" style="mask: url(#SVGMask);">
  <rect id="rect" width="100" height="100" fill="#f90"/>
  <rect id="rect" width="50" height="100" fill="#fff"/>
 </g>
</svg>
<figcaption>Mask 2+ elements Safari bug</figcaption>

在上面的代码中,我有一个橙色 <rect> 作为背景颜色,白色 <rect> 占据了一半的 viewBox,然后我将它们包裹在 <g> 中并应用给全团戴口罩。

此设置在 Firefox 和 Chrome 中都能正常工作,但在 Safari 中效果不佳。如您所见,背景中的橙色在逐渐消失时透过白色显示出来。看起来面具是分别应用于前后矩形而不是一次应用于整个组。

有人对此错误有解决方案或解决方法吗?它发生在 OSX Safari 和 iOS Safari 上。 (我的用例比这更复杂,但我创建了这个简化的示例来演示错误)。

对此有一个(hacky)解决方法 - 但它确实有效。挑战在于让蒙版将其输入视为位图而不是叠加的形状。您可以踢 Safari 来执行此操作,方法是在形状组和蒙版之间的组上插入一个虚拟过滤器。进行以下更改:

将此添加到您的 SVG defs:

<filter id="dummy-filter>
   <feColorMatrix type="saturate" values="1"/>
</filter>

并将您的绘图标记更改为:

<g id="combined" ... etc.
 <g filter="url(#dummy-filter)">
   <rect ... etc.
   <rect ... etc.
 </g>
</g>