水無月ばけらのえび日記

bakera.jp > 水無月ばけらのえび日記 > SVGをobject要素で活用する

SVGをobject要素で活用する

2012年1月31日(火曜日)

SVGをobject要素で活用する

更新: 2012年2月24日23時20分頃

SVGというものはずっと昔からありました。かつてはブラウザ側の対応がいまいちで、プラグインを入れたりしないと表示できなかったりもしており、あまり使われていませんでした。しかしIE9がSVGに対応したことで、かなり使えるようになってきた印象があります。最近では仕事でもガチでSVGを使うことが増えてきています。

SVGの特長のひとつは、ベクターグラフィックなので伸び縮みに強いという点です。サイズ可変の領域にうまい具合に背景を敷きたいときには便利です。そして、最近はサイトのコンテンツ全体がサイズ可変ということも増えてきました。というか元々可変ではあると思うのですが、Media Queries (www.w3.org)を使った派手な変更を伴うパターンが増えてきて、画像のサイズを大幅に変更したいケースが増えてきています。

写真などはJPEG画像を拡大・縮小してもそれほど違和感はないのですが、細い線で構成された図や、エッジのはっきりしている幾何学的な図形などは、GIFやPNGを拡大・縮小すると線がぼやけてしまい、はっきりと劣化が分かってしまいます。特に、CIやVI (企業のロゴやシンボルマークなど) はぼやけてしまうとよろしくありません。そこで、このような画像もSVGにしたい、というニーズが出てきます。

しかし、SVGにはIE6~8が対応していないという問題があります。背景に使う分には、画像が見えなくてもたいして問題はありません (というか、画像が見えなくても問題ないように作っています)。しかし、画像無効環境でもないのにロゴが見えないとなると、これは厳しすぎます。

※本当はIE9にしろと言いたいところですが、Windows XPにはIE9が入りませんし、社内にActiveXやVBScriptに依存したどうしようもないアプリがあってIE6が捨てられないというどうしようもない企業もあります。

そこで、ロゴとしてSVG画像を貼りつつ、SVGに対応していない環境ではPNG画像を表示させる、ということがやりたくなるわけです。

仕様的にはこれは簡単です。object要素を使ってSVG画像を貼り、その中でimg要素を使って代替のPNG画像を指定すれば良いのです。この方法は14年前(!)のHTML4.0からあったやり方です (HTML4.0 13.3.1 Rules for rendering objects (www.w3.org))。昔はobject要素への対応がおかしいブラウザもありましたが、最近のブラウザなら大丈夫なはず……。

実際にやってみると割と大丈夫……と思いきや、リンクがうまく行かないという問題が発覚。ロゴ画像はトップページへのリンクにしたいのですが、a要素の中に入れてもクリックできません。どうもobject要素の方が前面に出ていて、クリックイベントが後ろのアンカーに伝わらないようなのですね。iframeと同様、z-indexとかそういうレベルではない何かで前面扱いになるようです。

そこで出たアイデアが、「SVG画像自体にリンクを設置する」というもの。SVGにもa要素 (www.w3.org)があり、xlink:href属性でリンク先のURLを指定すると、HTMLのa要素と同じように働きます。で、試してみたら……なんと、object要素の中にリンク先のサイトが表示されて大爆笑。これは予想外でした。まあ、HTMLをobject要素で埋め込んだらそういう挙動になるでしょうから、分からないでもないのですが。

いちおうtarget属性 (www.w3.org)もあるのですが、そもそも、画像自体にリンクがついているのはあまり望ましくありません。同じ画像を使いつつ、リンクさせたくないという場合もあるからです。また、ロゴ画像のSVGはIliustratorからの書き出しで、XMLを手動で直すのは避けたいという事情もありました。

結局、pointer-events (www.w3.org)をnoneに設定すると背後のアンカーにイベントが渡るということで、object要素に style="pointer-events:none;" を設定して解決。また、ポインタが手の形にならない問題もあったりして、それはスクリプトで解決したり。

とまあ、いろいろ面白いことがあった訳ですが、何とか解決。SVGも、もう業務で使えるレベルになってきていると思います。

※あわせて読みたい: SVGをobject要素で表示してリンクにする (subtech.g.hatena.ne.jp)

関連する話題: Web / HTML / SVG

最近の日記

関わった本など