web-dev-qa-db-ja.com

filter(drop-shadow)によってSafariでSVGが消えるのはなぜですか?

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で何か変更がありましたか?

11
Kirkman14

おそらく少し遅れますが、念のために答えを残しておきます。私はSafariでも同じ問題を抱えていましたが、これはSafariの問題/バグのようだとわかりました。このバグを回避するには、SVGタグをdivなどの別のHTMLタグでラップし、例で行ったようにこの要素にドロップシャドウフィルターを適用します。ここでは、ラッパー要素で変更された例があります

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

お役に立てば幸いです。

25
Mauro Gava

ブラウザは物事を異なる方法で計算し、何らかの理由でSafariはあなたを嫌っています。笑。

ただし、代わりにSVGフィルターを使用する必要があります。それらははるかに信頼性があります。

ソース-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> 

お役に立てば幸いです。

3
user5473076

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

1
dmosberger

また、これが発生したときに、ロードインジケーターが回転を停止することはありませんでした。また、影を設定するスタイルタグ付きのSVGを別のウィンドウで開いた場合、影はありませんでした。解決策は、SVGフィルターを使用し、それが設定された要素を複製して、画像のサイズが変更された場合にモバイルサファリがピクセル化しないようにすることでした。例:ここで説明されているように https://stackoverflow.com/a/52250105/1267201

0
zavr

<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-32024398

0
Neal Lambert

私の場合、SVGフィルターを使用していたため、CSSソリューションを実際に適用することはできませんでした。代わりに、ページの読み込み後にJavascriptを介してCSS変換を適用することで、SVGを表示させることができました。プレーンJSの例を次に示します。

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

これが機能するかどうかを知りたい場合は、ブラウザーのサイズを変更した後、またはインスペクターを使用してCSSスタイルルールを変更した後にSVGが表示されるかどうかを確認してください。

0
Mike42