[SVG] clipPath要素はdefs要素で囲みましょう。

ブラウザごとにSVGコードの解釈が違うパターンを見つけたのでメモ。

clipPath要素に関するブラウザ間の解釈の違い

SVGにはクリッピングパスを定義するためのclipPathという要素があります。

以下はclipPath要素(詳しい内容は省略)とcircle要素を1つずつ含んだSVGコードの例になります。

さて、ブラウザがこのSVGコードを処理した場合、どのようにDOMツリーに展開されるのでしょうか?普通に考えると以下のようになるかと思います。

  • svg
    • clipPath
    • circle

まあ当然ですよね。
ですが、Safari(バージョン5.1.7)では以下のようなDOMツリーに展開されてしまいます。

  • svg
    • clipPath
      • circle

なぜかcircle要素がclipPathの子要素になってます。
これだと意図したとおりにSVG画像は表示されません。

ちなみに、Google ChromeやFirefoxの最新版で確認したところ上記のような問題は起きず、正しいDOMツリーに展開されました。

解決策

いろいろ試したところ、defs要素でclipPath要素を囲めばいいみたい。
これを使うことでブラウザ間のSVGコードの解釈の差がなくなります。

以下はSVGコードの例。

上記のコードはどのブラウザでも以下のようにDOMツリーに展開されます。

  • svg
    • defs
      • clipPath
  • circle

ちなみに、defs要素は「あとから参照するための要素」を定義するために使う要素。

SVGの仕様書を読む限り、svg要素の直下にclipPathを定義しても問題ないはずなんですが、「Safariのバグ」と結論付けちゃっていいものなのでしょうか。

詳細目次 – SVG 1.1 (第2版)

まとめ

まとめると、表題の通り「clipPath要素はdefs要素で囲みましょう」という事なのですが、なんだが腑に落ちないですね。

Safariのバグだとすれば、既知の問題なのかどうかも気になります。既知でない場合はどこに報告すればいいんだろう。

同じような問題に直面したことがある方いらっしゃいましたら、ぜひ教えて下さいね。
それでは!