外部のCSSを参照したSVGは思うように参照できるか
おおおお、なるほどー!
ただやっぱり、CSSの外部参照は厳しそうですね。
SVGから外部スタイルシートを参照するその他の方法
SVGから外部CSSを読み込む方法としては、記事にあるxml-stylesheet
PIを使う他に、SVGの<style>
要素を使うという手がある。SVGでCSS使う際にも @import が使えるので、そこから参照してやればよい。あ、XMLだから要素の内容はちゃんとCDATAセクションで囲ってね。
<style><![CDATA[ @import url(external.css); ]]></style>
<svg:style>
を使ったSVGファイルを直接開いたら、PIの例と同じようにChrome (dev), Firefox (beta), Opera (Next)は外部スタイルシートが適用された。ただSafari 5.1はCSSが適用されず。どうやら去年からの一年間にWebKitがちょっと良くなったらしい。
他にCSSを外部参照する仕組みがないか調べてみたら、Doug Shepersのエントリが引っかかった。SVGの<style>
も紹介されているけど、彼が思いついたのはHTMLの<link>
で参照させるというもの。HTMLのNamespace (http://www.w3.org/1999/xhtml
) を宣言して、HTMLの<link>
要素をNamespace prefix付きでそのまま書けばいい。
<html:link rel="stylesheet" href="external.css" />
すごいよDoug…。とてもXMLっぽい使い方だ。
というわけで<html:link>
を使ったSVGファイルも作ってみた。こっちはなんとSafari 5.1もOKだった。
SVGのreferencing modes
さて、どの方法でも直接開くと外部CSSファイルを参照できることがわかった。でも件の話はbackground-image
での参照について。試したところどちらも、Opera以外でダメだった。
となると、たぶん想像されてる中にあると思うんですが、原因はSVGのreferencing modesでしょうねと。
SVG画像にはいろんな参照方法が考えられる。<img>
, background-image
で画像として読み込む方法と、<object>
や<iframe>
からオブジェクトとして埋め込む方法。
このうち、画像として読み込む<img>
やbackground-image
は、セキュリティなどの絡みで制限がかけられている。SVG内のスクリプトは実行されない、クリックイベントなどを受け付けない。<object>
などオブジェクトはOK。
で、どうやら外部参照も制限されるもののひとつらしい。ためしに<object>
経由で参照させてみるとうまくいった。
この制限される項目と、埋め込む方法の組み合わせは“referencing mode”として、SVG Integrationなる文書にまとめられている。書いたのはさっき紹介したDoug。
この文書では<img>
で推奨されるモード、background-image
で推奨されるモードどちらでも外部参照が“yes”となっている。ただ、これが正式な仕様というわけでもないので、実装は違う。
Same-originなリソースでも参照は難あり
外部参照については、same-originなリソースに限定しようかというノートがSVG WGのWikiにある。
ただ、same-originなリソースでも、それがまだどこかにリダイレクトしていたら問題で、という懸念事項が書かれている。
で、こういった理由をふまえて、Mozillaは外部参照をしないように実装を変えた経緯があったみたい。Firefox 4のbeta段階で修正が入っている。
外部参照をしたいユースケースとして提示されていたのが、SVGファイル内部からバイナリ画像であったり他のSVGファイルを参照したい、というもの。これらの場合はdata: URLにすればいいだろう的なアドバイスがなされている。
ただ、ここでしたいのは外部CSSの情報を適用することなので、ちょっと解決できなそう。