【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が良い時もあるのかな。