为什么过滤器(drop-shadow)会导致我的SVG在Safari中消失?

时间:2016-04-18 22:20:33

标签: css svg safari mobile-safari css-filters

我正在使用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中有什么变化?

6 个答案:

答案 0 :(得分:24)

可能有点晚了,但万一我会留下你的回答。我遇到了与Safari相同的问题,我发现这似乎是一个Safari问题/ bug。您可以解决此错误,只需将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) );
}

希望有所帮助!

答案 1 :(得分:3)

浏览器以不同的方式计算事物,并且出于某种原因,Safari讨厌你。洛尔。

但是,您应该使用SVG过滤器。它们更可靠。

<强> SOURCE - w3schools

 <svg height="140" width="140">
  <defs>
    <filter id="f3" x="0" y="0" width="200%" height="200%">
      <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 width="90" height="90" stroke="green" stroke-width="3"
  fill="yellow" filter="url(#f3)" />
</svg> 

希望有所帮助!

答案 2 :(得分:1)

我在Safari中也遇到了类似的问题:SVG对象(例如线条)在应用滤镜效果后会消失。相同的代码在Chrome和Firefox中运行良好。该代码是Angular应用程序的一部分。事实证明,问题是由Angular使用“基本”标签触发的。

似乎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

答案 3 :(得分:0)

就我而言,我使用的是SVG过滤器,所以我无法真正应用CSS解决方案。相反,我能够通过在页面加载后通过Javascript应用CSS转换来显示SVG。这是普通JS中的一个例子:

setTimeout(function(){
 document.getElementById("svg-element").style.display = "block";
},10);

如果您想知道这是否有效,请在调整浏览器大小或使用检查器修改CSS样式规则后查看SVG是否显示。

答案 4 :(得分:0)

在发生这种情况时,我还有一个加载指示器从未停止旋转。同样,在单独的窗口中打开带有设置阴影的样式标签的SVG时,也没有阴影。解决方案是使用SVG过滤器,并确保复制设置了该元素的元素,以便在调整图像大小时,移动浏览器不会对它进行像素化。例如,如此处https://stackoverflow.com/a/52250105/1267201

所述

答案 5 :(得分:0)

由于我们使用<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