2016-04-18 4 views
9

Ich entwickle eine App mit D3.js. Ich wurde für eine Weile abgelenkt und kam kürzlich dazu zurück. Heute stellte ich fest, dass die SVG-Karte in der App zwar in der Vergangenheit gut funktionierte, aber nicht mehr auf Mobile Safari (iOS 9.3.1) oder Desktop Safari (Version 9.11 (11601.5.17.1)) angezeigt wird.Warum verursacht Filter (Schlagschatten), dass mein SVG in Safari verschwindet?

Ich extrahierte das SVG und eine einzelne Stilregel und legte sie auf CodePen, um zu illustrieren, was passiert. In Chrome wird dieser Stift gut aussehen. In Safari wird es komplett leer sein.

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

Wenn Sie das DOM in Safari überprüfen, finden Sie, dass die Wege sind, und sie sind die richtigen Formen. Sie scheinen nur unsichtbar zu sein. Deaktivieren Sie die Stilregeln im Inspektor bewirkt, dass die gesamte Karte magisch erscheinen (ohne Schlagschatten, natürlich)

Die Stilregel ist sehr einfach:

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

Kann jemand empfehlen, warum dies nicht funktioniert? Habe ich etwas falsch gemacht oder hat sich etwas in Safari geändert?

Antwort

17

Wahrscheinlich ist ein bisschen spät, aber nur für den Fall, dass ich Ihnen meine Antwort hinterlassen werde. Ich hatte das gleiche Problem mit Safari und ich fand heraus, dass dies ein Safari-Problem zu sein scheint. Sie können diesen Fehler umgehen, indem Sie einfach Ihr SVG-Tag mit einem anderen HTML-Tag wie ein Div umschließen und das Drop-Shadow-Filter auf dieses Element anwenden, wie Sie es in Ihrem Beispiel getan haben. Sie hier Ihr Beispiel

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

Hoffnung mit dem Wrapper-Elemente geändert, das hilft!

+1

Dies scheint die perfekte Problemumgehung zu sein.Ich versuche es und wähle es wahrscheinlich als Antwort aus. – Kirkman14

+0

das hat gut für mich funktioniert. Es sollte die akzeptierte Antwort sein –

+0

Vielen Dank für diese Lösung, super Leichtigkeit und super sauber. Sollte die akzeptierte Antwort sein. – Thasmo

1

Browser berechnen Dinge anders und aus irgendeinem Grund hasst Safari Sie. Lol.

Allerdings sollten Sie stattdessen SVG-Filter verwenden. Sie sind viel zuverlässiger.

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> 

Hoffnung, das hilft!

+0

Mit ein paar Optimierungen funktioniert dieser Code. Aber das Ergebnis ist nicht so sauber wie die CSS-Lösung. Ein Problem ist, dass einige der SVG-Polygone mit Streifen statt mit Volltonfarben gefüllt sind, wodurch der Schatten in der Nähe dieser bestimmten Polys heller erscheint. – Kirkman14

+0

Eine ähnliche, aber etwas bessere Technik kann [hier] gefunden werden (https://docs.webplatform.org/wiki/svg/tutorials/smarter_svg_filters#Chaining.2C_splitting_and_merging_effects:_building_a_drop_shadow_with_feOffset.2C_feFlood.2C_and_feMerge). Hat immer noch das Problem der Leichtigkeit, aber es ist nicht so ausgeprägt, wenn Sie einen grauen Schatten anstelle eines schwarzen verwenden. – Kirkman14

0

In meinem Fall benutzte ich einen SVG-Filter, so dass ich die CSS-Lösung nicht wirklich anwenden konnte. Stattdessen konnte ich die SVG anzeigen, indem ich nach dem Laden der Seite eine CSS-Umwandlung über Javascript anwendete. Hier ist ein Beispiel im Klar JS:

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

Wenn Sie wissen wollen, ob dies funktionieren wird, ob die SVG zeigt, nachdem Sie den Browser oder die Größe eines CSS-Style-Regel ändern Sie den Inspektor verwenden.