インラインSVGを使う上で問題となること
ようやくIE8環境の終焉が見えてきたところでSVG普及の目処が立ちつつある今日このごろですが,それでも要件上SVG非対応環境を無視できないことは未だにあるかと思います.
すると問題となるのがSVG画像のフォールバックによる対処です.大抵はPNG画像を用いて代替とするのでしょうが,HTMLのインラインSVG機構を使っていた場合結構実現が難しかったりします.
この問題への対処策は本ブログで紹介してきたとおりで,下記の記事で触れています.
- svgのフォールバック手法あれこれ
http://defghi1977-onblog.blogspot.jp/2012/09/svg_27.html
(こちらでも紹介されているがおいらのほうが早い!勝った!) - スクリプトレスなsvgのフォールバック手法・まとめ
http://defghi1977-onblog.blogspot.jp/2013/01/svg_21.html
要はforeignObject要素を使って次のようなコードを記述せよってことです.
<!DOCTYPE html>
<html>
<body>
<svg width="200px" height="200px">
<rect x="50" y="50" width="100" height="100" fill="yellow"/>
<foreignObject display="none">
<img src="img.png"/>
</foreignObject>
</svg>
</body>
</html>
こうすると,
- SVGをサポートしているブラウザではimg要素が隠れる
- SVGをサポートしているブラウザではimg要素が表示される
…と思われましたが,
こちら(SVGをIE等のブラウザ対応を考慮して使う方法まとめ(SVGのフォールバック画像など))
で指摘されているように,これでは常にimg.pngの内容が読み込まれてしまうのです!
少数派となっているSVG非対応ブラウザのために,大半を占める環境にimg.pngをダウンロードさせるというのはいかにも無駄が多いと言わざるを得ません.
じゃあこの他にインラインSVGのフォールバックってどうやりゃいいのよ?というのが今回の課題です.
HTMLパーサーを使った対処
そこで今回紹介するのがHTMLパーサーの挙動を逆手に取ったものです.とりあえず次のコードを見てください.
<!DOCTYPE html> <html> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8"/> <style type="text/css"> svg, #fallback{ width:200px; height:200px; } #fallback{ background-image:url(fallback.png); background-size:200px 200px; } svg+#fallback{ display:none; background-image:none; } </style> </head> <body> <svg> <rect x="10" y="10" width="180" height="180" fill="blue"/> <div id="fallback"></div> </svg> </body> </html>
そこで質問です.これをfirefox等のSVGをサポートするwebブラウザで表示するとid="fallback"が付けられたdiv要素はどこに配置されるでしょうか?
htmlコードの通り「svg要素配下にdiv要素が格納される」と考えた方はハズレです.実はSVG要素の直後に配置されます.すると,スタイルシートの「svg+#fallback」の記述が有効となります.
一方SVGをサポートしないwebブラウザ(ie8,android2.x系)ではsvg要素を解釈できず,上記のような再配置が発生しません.つまり「#fallback」の記述が有効となります.
よってcssによる画像の読み込み有無の振り分けが可能になるのです!
下は実際の動作例です.(android2.x系は@rikuo氏に確認していただきました.感謝!)
奇妙な動作に見えますか?ですが,これはれっきとしたHTML5の仕様なのです.
http://www.whatwg.org/specs/web-apps/current-work/multipage/syntax.html#creating-and-inserting-nodes
ですから今後動作しなくなることもありません.
NOTE:
http://css-tricks.com/svg-fallbacks/
にあるimageタグトリックは個人的には好かんのですが,こっちのほうが簡単かも知れません.
何れにせよ複数の選択肢があるってのは良いことです.
0 件のコメント:
コメントを投稿