HTMLにSVGを埋め込む際にハマったこと


HTML5 Powered with Graphics, 3D & EffectsHTML5の話題の高まりにより、一度は枯れた技術となっていたSVGにも再び光が当たるようになりました。SVGを使えば、ベクターデータをブラウザに表示させることができます。今回はSVGをブラウザで表示させる際にハマった問題を紹介します。
 

SVGをブラウザで表示させる方法

 
SVGをブラウザで表示させる方法は何種類かあり、それぞれ違いがあります。

●objectタグでの埋め込み
object要素にて、外部のリソースとしてSVGを組み込みます。object内のSVGはインラインフレームと同様に、別のウィンドウとして扱われますが、contentDocumentで取得することができ、外部JSから操作可能です。

HTML

<object type=”image/svg+xml” data=”mySvg.svg” height=”240px” width=”230px” id=”svgID”> </object>

JavaScript

var svg = document.getElementById(“svgID”).contentDocument;

●dataスキームでの埋め込み
img要素のsrc属性、CSSのbackground-imageなどのdataスキームを使って組み込む方法です。
 
●XHTMLへの埋め込み
SVGはXMLなので、名前空間を指定すれば、XHTML中に混在させることが可能です。

名前空間の設定例

<html xmlns=”http://www.w3.org/1999/xhtml”
xmlns:svg=”http://www.w3.org/2000/svg”
xmlns:xlink=”http://www.w3.org/1999/xlink”>

●インラインSVG
XHTMLに埋め込む場合、名前空間を記述しなければなりませんでしたが、インラインSVGの場合、HTML内に直接記述することができます。Firefox 4、IE9、 Chrome7、Safari5で使用することができます。また、IOS5のMobileSafariもインラインSVGに対応しました。
 

Safariでは背景が透過にならない?

 
SVGをobject要素を使って埋め込んだ場合、ChromeやFirefoxでは背景が透過して表示されるのですが、Safari(PC版、iPhone版共に)では透過されず、背景が白で表示されてしまういう問題にぶつかりました。Google グループの「html5j.org」で質問してみたところ、W3CのSVGの仕様としては、背景とアルファブレンディングされるのが仕様であること、この動作はWebKitのバグだったということが分かりました。


Safari 5.0.5での表示(左) Safari5.1.1での表示(右)

そこで、それまで表示の確認に使っていたSafariのバージョンを、Safari 5.0.5 / iOS4.3.2(MobileSafari)からそれぞれSafari5.1.1、iOS5にアップグレードしたところ、どちらも問題なく透過表示されました。このバグに対する修正が入ってるWebKitのバージョンは534以降のようなので、修正後のWebKitをベースにしたブラウザであればこの問題は起こらないと思われます。

【関連リンク】
バグ詳細 / WebKit変更履歴

WebKitのバージョンが534以降のブラウザを使っているユーザには透過SVGを表示させることができますが、以前のバージョンでは背景が表示されたままになってしまうため、今回はobject要素を使わずXHTMLへ埋め込む方法で対処しました。iOS5ではインラインSVGがサポートされたので、デモであればインラインSVGが一番簡単かもしれません。
 

Content-Typeに注意

 
HTMLに外部SVGファイルを埋め込んだのに表示されない場合、HTTPヘッダーのContent-Typeが『image/svg+xml』になっているか確認します。『text/plain』になっている場合があるので、pacheの設定ファイル(httpd.conf)で以下を設定します。

AddType image/svg+xml .svg
AddType image/svg+xml .svgz