【SVG】imgタグで開くかobjectタグで開くかの違い

いろんなサイトで

SVGファイルの開き方はimgでもobjectでもどっちでもイイ

みたいなことが書いてありますが、開き方による明確な違いを発見したのでメモ。

imgタグでSVGを開く

たとえばこんなディレクトリ構成のファイルがあるとします。

root/
  ├ index.html
  └ img/
    ├ main.svg
    └ sub.svg

index.htmlの中でmain.svgを読み込みます。
またmain.svgの中でsub.svgを読み込みます。
ソースはこんな感じ

index.html

<!DOCTYPE html>
<img src="./img/main.svg" />

img/main.svg

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
  <image width="100" href="sub.svg" />
</svg>

img/sub.svg

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
  <ellipse cx="50" cy="50" rx="30" ry="30"/>
</svg>

で、このhtmlを開くと何が起きるかと言うと
main.svg経由で読み込んだsub.svgの丸が表示されるかと思いきや..
実際は表示されない。

imgタグの場合、svg内での読込みはindex.htmlからの相対パス

表示されない理由はmain.svgの中に書かれてる<image width="100" href="sub.svg" />は、読み込み元のindex.htmlからの相対パスだから。
なのでちゃんと表示される正しいパスはimg/sub.svg

でもさー。
何でsvgの呼び出し元を意識しながら書かなきゃなんだよ! つらい。

objectタグの場合、svg内での読込みはsvgからの相対パス

そこで読み込みをimgタグからobjectタグに変えてみると。
index.html

<!DOCTYPE html>
<object type="image/svg+xml" data="./img/main.svg" width="256" height="256"></object>

これだと表示される! つまりカレントディレクトリはsvgファイルのパスになってるっぽい。

svgの中身が見れるかどうかも違う

document.querySelector()等でimgタグなりobjectタグを取得した時に
imgタグの場合はsvgの中身を見ることができないが、
objectタグの場合はsvgの中身が見れた。
(ただしクロスオリジン等で弾かれる可能性あり)

まとめ

結果はこんな感じ。

読み込み方 svg内のカレントディレクト htmlからsvgの中身が見れるか
imgタグ 呼び出し元のファイルのパス 見れない
objectタグ svg自身のパス 見れる(クロスオリジン注意)

objectの方が良さそうに見えるけど、imgが良い時もあるのかな。