Why is filter(drop-shadow) causing my SVG to disap

2019-01-24 06:38发布

问题:

I am developing an app using D3.js. I was sidetracked for a while, and recently came back to it. Today I found that, though it worked fine in the past, the SVG map in the app no longer displays on mobile Safari (iOS 9.3.1) or desktop Safari (v9.1 (11601.5.17.1) ).

I extracted the SVG and a single style rule and put them on CodePen to illustrate what happens. In Chrome, this pen will look fine. In Safari, it will be completely blank.

https://codepen.io/Kirkman/pen/pyKzeX

If you inspect the DOM in Safari, you find that the paths are there, and they are the right shapes. They just seem invisible. Unchecking the style rules in the inspector causes the entire map to magically appear (without the drop shadow, obviously)

The style rule is very straightforward:

svg {
    -webkit-filter: drop-shadow( 2px 2px 4px rgba(0,0,0,.4) );
    filter: drop-shadow( 2px 2px 4px rgba(0,0,0,.4) );
}

Can anyone suggest why this isn't working? Did I do something wrong, or has something changed in Safari?

回答1:

Probably is a little late, but just in case I will leave you my answer. I had the same problem with Safari and I figured out that this seems to be a Safari issue/bug. You can work around this bug just wrapping your SVG tag with another HTML tag like a div and apply to this element the drop-shadow filter as you did in your example. Here you have your example modified with the wrapper element

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) );
}

Hope that helps!



回答2:

Browsers calculate things differently and for some reason Safari hates you. Lol.

However you should be using SVG Filters instead. They are much more reliable.

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> 

Hope that helps!



回答3:

In my case, I was using an SVG Filter, so I couldn't really apply the CSS solution. Instead, I was able to get the SVG to show up by applying a CSS transformation via Javascript after the page loads. Here's an example in plain JS:

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

If you want to know if this will work, see if the SVG shows up after you resize the browser or modify a CSS style rule using the inspector.



回答4:

I also had loading indicator never stopping to rotate when this happened. Also when SVG with a style tag which set the shadow was opened in a separate window, there was no shadow. The solution was to use an SVG filter, and make sure to duplicate the element on which it was set, so that if the image is resized, the mobile safari would not pixelate it. E.g., as described here https://stackoverflow.com/a/52250105/1267201