为啥过滤器(阴影)导致我的 SVG 在 Safari 中消失?
Posted
技术标签:
【中文标题】为啥过滤器(阴影)导致我的 SVG 在 Safari 中消失?【英文标题】:Why is filter(drop-shadow) causing my SVG to disappear in Safari?为什么过滤器(阴影)导致我的 SVG 在 Safari 中消失? 【发布时间】:2016-08-10 20:39:15 【问题描述】:我正在使用 D3.js 开发应用程序。我有一段时间被转移了,最近又回来了。今天我发现,虽然过去运行良好,但应用程序中的 SVG 地图不再显示在移动版 Safari (ios 9.3.1) 或桌面版 Safari (v9.1 (11601.5.17.1) ) 上。
我提取了 SVG 和单个样式规则并将它们放在 CodePen 上以说明发生了什么。在 Chrome 中,这支笔看起来不错。在 Safari 中,它将完全空白。
https://codepen.io/Kirkman/pen/pyKzeX
如果您在 Safari 中检查 DOM,您会发现路径在那里,并且它们的形状正确。他们只是看起来不可见。在检查器中取消选中样式规则会导致整个地图神奇地出现(显然没有阴影)
样式规则很简单:
svg
-webkit-filter: drop-shadow( 2px 2px 4px rgba(0,0,0,.4) );
filter: drop-shadow( 2px 2px 4px rgba(0,0,0,.4) );
谁能建议为什么这不起作用?是我做错了什么,还是在 Safari 中发生了一些变化?
【问题讨论】:
我在 2016 年向 Apple 提交了一份错误报告,他们说他们在 iOS 11 中修复了这个问题。bugreport.apple.com/web/?problemID=25788891 【参考方案1】:由于我们使用了<base>
标签,我在 Angular 应用中遇到了同样的问题。
我将它添加到控制器中:
$scope.basePath = window.location.href;
然后在模板中我添加了过滤器的基本路径:
<g ng-attr-filter="url(basePath#filter1_d)">
希望这可以帮助任何使用 Angular 的人。查看 Github 中的此评论以获取更多信息:https://github.com/airbnb/lottie-web/issues/360#issuecomment-320243980
【讨论】:
【参考方案2】:我在 Safari 中遇到了类似的问题:一旦应用了滤镜效果,线条等 SVG 对象就会消失。相同的代码在 Chrome 和 Firefox 中运行良好。该代码是 Angular 应用程序的一部分。原来问题是由 Angular 使用“base”标签触发的。
Safari 似乎将基本标记应用于嵌入的 SVG 图像中的片段名称,而 Chrome 和 Firefox 则没有。这段代码说明了这个问题:
<html>
<head>
<base href="/">
</head>
<body>
<svg>
<filter filterUnits="userSpaceOnUse" id="glow">
<feGaussianBlur stdDeviation="1.5"></feGaussianBlur>
</filter>
<line x2="99" y2="99" stroke="red" filter="url(#glow)"></line>
<line y1="99" x2="99" stroke="green" filter="url(/_display/#glow)"></line>
</svg>
</body>
</html>
在 Safari 上,只会显示绿线,而 Chrome 和 Mozilla 会显示红线和绿线。
jsfiddle demonstrating the problem
【讨论】:
事实证明这对我来说是破坏 svg 过滤器的原因。您是否为此找到了解决方法?如果能够在 Safari 中同时使用<base>
和 svg 过滤器,那就太好了。
我知道的唯一解决方法是在过滤器 url 中指定一个绝对路径(如第二个示例所示)。如果过滤器是在 javascript 中创建的,您可以简单地在相对路径前加上 window.location 以使其成为绝对路径。我确实向 Apple 提交了错误报告,但尚未收到回复。【参考方案3】:
当这种情况发生时,我的加载指示器也永远不会停止旋转。此外,当带有设置阴影的样式标签的 SVG 在单独的窗口中打开时,没有阴影。解决方案是使用 SVG 过滤器,并确保复制设置它的元素,以便在调整图像大小时,移动 safari 不会对其进行像素化。例如,如此处所述https://***.com/a/52250105/1267201
【讨论】:
【参考方案4】:就我而言,我使用的是 SVG 过滤器,因此我无法真正应用 CSS 解决方案。相反,我能够在页面加载后通过 Javascript 应用 CSS 转换来显示 SVG。下面是一个普通 JS 的例子:
setTimeout(function()
document.getElementById("svg-element").style.display = "block";
,10);
如果您想知道这是否可行,请查看在您调整浏览器大小或使用检查器修改 CSS 样式规则后是否显示 SVG。
【讨论】:
【参考方案5】:可能有点晚了,但以防万一我会给你我的答案。我对 Safari 也有同样的问题,我发现这似乎是一个 Safari 问题/错误。您可以解决此错误,只需将您的 SVG 标记与另一个 HTML 标记(如 div)包装起来,然后像在示例中所做的那样将阴影过滤器应用于此元素。 在这里,您使用包装器元素修改了示例
https://codepen.io/mauromjg/pen/rLaqWG
<div class="svg-wrapper">
<svg>...</svg>
</div>
//CSS
.svg-wrapper
-webkit-filter: drop-shadow( 2px 2px 4px rgba(0,0,0,.4) );
filter: drop-shadow( 2px 2px 4px rgba(0,0,0,.4) );
希望有帮助!
【讨论】:
这似乎是完美的解决方法。我会试一试,可能会选择这个作为答案。 这对我来说效果很好。这应该是公认的答案 非常感谢这个解决方案,超级简单,超级干净。应该是公认的答案。 在 iOS 上(在 web 视图或 Safari 本身中——在 11.3 下测试),似乎这种解决方法可能会导致一些间歇性损坏效果和屏幕撕裂,类似于here 所描述的,这不是立即显而易见的.只是提醒一下。 这似乎不是一种解决方法(或至少不再是)。将样式放在 svg 上而不是 codepen 中的包装器上会导致放大时相同的模糊 svg。codepen.io/sarahannnicholson/pen/abvYvEp 与 codepen.io/mauromjg/pen/rLaqWG 在 Safari 移动设备中会导致相同的模糊 svg。【参考方案6】:浏览器计算方式不同,出于某种原因,Safari 讨厌你。哈哈。
但是,您应该改用 SVG 过滤器。它们更可靠。
SOURCE - w3schools
<svg >
<defs>
<filter id="f3" x="0" y="0" >
<feOffset result="offOut" in="SourceAlpha" dx="20" dy="20" />
<feGaussianBlur result="blurOut" in="offOut" stdDeviation="10" />
<feBlend in="SourceGraphic" in2="blurOut" mode="normal" />
</filter>
</defs>
<rect stroke="green" stroke-
fill="yellow" filter="url(#f3)" />
</svg>
希望有帮助!
【讨论】:
经过一些调整,这段代码就可以工作了。但结果不如 CSS 解决方案干净。一个问题是我的一些 SVG 多边形填充了条纹而不是纯色,这导致阴影在这些特定多边形附近看起来更亮。 可以在here 找到类似但稍好一些的技术。仍然有亮度问题,但如果你使用灰色阴影而不是黑色阴影,它就不那么明显了。以上是关于为啥过滤器(阴影)导致我的 SVG 在 Safari 中消失?的主要内容,如果未能解决你的问题,请参考以下文章
如何通过 CSS 将阴影过滤器应用于 SVG 特定元素/路径