Blog

Published on

RSS

SVG導入のためのレガシーブラウザ振り分け

やっと少しずつ現実的になってきた、webで使える夢のベクター画像SVG。拡大し放題だししかもテキストデータでXMLだわ容量小さいわってことで何ともかわいいヤツ。 当方ものすごくSVG好きです。

13.5pxでの表示
拡大してもなめらかSVGちゃん (ちなみにこの画像自体はPNG)

SVGが使いたい

もともとサイトの素材画像はIllustatorで作ってたのもあり、実はローカル環境ではだいぶ前から画像はSVGにしてたんだけど、webでってなるとやはりネックになってくるのが、いつもの我らがInternet Explorer。caniuse.comによれば、SVG画像を普通の画像と同じ様に扱えるのはどうやらIE9以降。いくらなんでも現時点で8を切るわけにもいかず、SVG導入は将にIE待ち状態。いつも通りです。しかたなくSVGクオリティーはローカルで個人的に楽しむにとどまり、webに上げる用は別途PNG-24に書き出してました1

それでもヘッダの蛙ちゃんとかサイトロゴとかポイントになってて且つ管理しやすい部分はPHPとかCSSの方で振り分けてモダンブラウザにはSVGを渡すようにしていたのですが、いかんせん個別対応なので全部に対してやるのはしんどいしソースも汚くなるから最低限しかやってなかった。

しかしiPadもRetinaになり今後本格的にHiDPI時代がやってくるかと思うと、そろそろさらりと一足先に対応しておきたいところです。もう我慢できん。

で、「てかそもそもApacheが画像渡す時点で選別してもらえばいいんじゃん!」と気付き .htaccess で振り分けることにした。


.htaccess で Apache にやらせよう

つまり、今まで普通に画像を入れていたディレクトリの画像を本格的にSVGに入れ替えてしまい、SVGに対応しているモダンなブラウザは普通のそっちの画像を取りにいかせる。もうデフォルトはSVG。で、その一方でレガシーブラウザ用に、メインの画像ディレクトリと同じディレクトリ構造のPNG画像版を作り、そいつらが拾いにいった画像がSVG(Z)なら .htaccess で振り分けてリダイレクトをかける2

というわけで画像を入れてるディレクトリの .htaccess にこんな感じのことを書く。

# rewrite SVG -> PNG for legacy UA
RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} "MSIE [4-8]" [OR]
RewriteCond %{HTTP_USER_AGENT} "Firefox\/3\."
RewriteRule ^(.*)\.svgz?$ /_legacyImg/$1
.htaccessに書き足す

imgやCSSでSVGを表示できないレガシーなIEとFirefoxに対してだけリダイレクトをかける。/_legacyImg/ の部分には実際には サイトのルートから PNGをまとめたディレクトリまでのパスを入れます。

これだとCSSのcontentなんかで呼び出したときも、レガシーブラウザにはしれっとPNGを渡してくれる。かつSVG以外のPNGやJPEGの画像に対しては普通にメインのデータを渡すから、SVGを採用してる画像だけPNG版を用意すればいい。私は平生HTMLやCSSからSVGを呼び出すときに他の画像と全く同じように扱ってるので(つまりHTMLでも普通にimgタグで呼び出してる)、これならHTMLやCSS側に一切手を加える必要はないし、将来世の中に出回ってるUAが大方対応し終わったら.htaccessからその振り分けの記述だけ外せばいい。そいで代替PNGディレクトリをゴミ箱にダンク。らくちんクリーン。

あ、あと私はMultiviewsをonにして拡張子省略して書くようにしてるので3、そうじゃない設定の場合はその辺良きに計らう必要がある。と言ってもPNG決め打ちとかにしちゃえばいいだろうから、こんな感じかな。

RewriteRule ^(.*)\.svgz?$ /_legacy/$1.png
Multiviews off版

ApacheがUAに画像渡す時点で振り分けてるので、BlogだろうがCMSだろうがなんだろうが同じ戦法でいけるはず。ただ一応言っておくとmod_rewriteが使えるサーバじゃないと使えない方法なのでご注意を。

最近はグリフ系はフォントに押し込んで表示させたりするのも流行みたいですが、なんだかそういうHackが行き過ぎた方法はあんまり好きではないので(同じ理由で CSS Sprite もあまり好きじゃない)導入には消極的。「やったらべんりだろうな」と思うこともなくはないけど。

今ではすっかりSVGなので、新しいiPad 入手した方はぜひそれで当方のサイトをご覧なってみては? 当の私がまだ見てないのですが、きっと滑らか。

いずれにせよ、これで当サイトもSVG解禁...!! 今後使いたい放題だと思うと胸が熱いです。

ラスター画像も今後Retina対応が迫られるのでしょうが、ひとまずベクター画像をベクター画像として扱えることに満足しきってます。やっとですよ。

ちなみに最近SVG導入に興味を持った方、こっそりこんなのあるよ。

  1. Macユーザしか来ないことがわかってるサイトを一つ管理しててそっちは既に昨年SVGに移行済み。
  2. たとえば、普段画像は "/_img/" ってディレクトリにまとめてたとしたら、 "/_legacyImg/" みたいのを作ってそっちに "/_img/" と同じディレクトリ構造で代替PNG画像を置く。 で "_img/" 内に .htaccess を書く。すると "/_img/dog/cow.svg" ってのを貰いにきたブラウザがSVGに対応してないヤツだったときに "/_legacyImg/dog/cow.png" を渡す。
  3. よくできたもんで拡張子なしで呼んでもsvgかそうじゃないかでちゃんと振る舞いは変わる。

7 Comments

SVGで保存するとGIFやJPG、PNGよりも容量大きくなります。なぜでしょうか?

1024jp @webmaster

> 天さん
もちろん画像のデータによってはSVGの方がデータ容量が大きくなることがあります。
体感だと16px程度の小さな画像はPNGやGIFの方が容量だけ見ると小さくなります。
また、ベクターデータではなくラスター(ビットマップ)データをSVGで書き出した場合は、
結局PNGなどをSVGでくるんでいるだけなので、そちらの方が大きくなります。

ただ、ソフトウェアによってはSVGに書き出すときに本来なら必要ないデータを含めたり、アンカーポイントの座標を細かく出しすぎたり(例えばpx単位で小数点4位)することがあります。
とくに、私は普段Illustrator CS3を使うことがおおいのですが、
このソフトウェアはSVG書き出し時に非表示にしているレイヤーも、
非表示のまま書き出し後のSVGデータに含めようとします。
そのため、例えばある写真をもとにトレースをして、その元画像は非表示にして、
アウトラインだけSVGに書き出そう、なんて思って操作をすると、
こっそり元画像データもSVGに含まれていた、ということが起こります。
もしXML形式の基礎的な知識があるなら、テキストエディタでSVGファイルの中を見て、
いらないタグがないか確かめてみると、原因がわかるかもしれません。

それ以外だと、SVGはwebに上げて使う場合はgzip圧縮をかけてsvgz形式で扱うのが一般的です。
svgz形式はsvg形式の1/2〜1/3くらいのサイズになります。

SVGデータのダイエットについてはちょうどBlogに書きたいなと思っていたところなので、
4月中に詳しく書く予定です。

SVGの勉強をしていてたどり着きました。
データの最適化なんかをいろいろ試してみましたが、こちらで紹介されている mod_rewrite をつかうと、できそうな気がしてきました。
SVGも既に実用レベルに達しているのかなと感じたのですが、サイト制作で利用するにあたって、他と比較して配慮すべき点などありますか?

1024jp @webmaster

> DriftwoodJPさん
はじめまして。
この.htaccessで振り分ける方法は、現在主流のJavaScriptなどを使う方法よりずっとスマートだと今でも思っております。

さて、配慮すべき点ですが、SVGがどういう過程で作られたかによってだいぶ変わってくるかとは思います。
すぐ思いつくところだと:

一般的なグラフィックソフト(Illustratorなど)から吐き出したものであるとすると、ムダなデータが入っている可能性があるので、その辺りのダイエットには気をつけた方が良いかなと思います。単に非表示にしていた下書きのビットマップ画像が含まれていてしまったり、ムダに小数点以下の精度の高かったりするとファイルサイズの肥大の原因になります。

あとは、ブラウザによって対応状況にムラがあるので、単純にSVGに対応している/していないではなくその辺を見極めながら技術を投入していく必要があるでしょう。フィルターやマスク、フォント系は手元の最新版ブラウザでは問題なく表示されていてもちょっと前のブラウザだと対応していなかったりします。そのときにも破綻がないようにしておくという一手間がかかります。
この辺はCSSの後方互換なんかと考え方は同じだと思います。

後方互換のお話で can i use を見たんですが、なるほどです。

http://caniuse.com/#search=svg

SVG形式で保存したときに、どんなXMLがはき出されるのかも考えて、元のイラレデータを作らないといけない感じでしょうか。

イラレとSVG仕様含め、ちゃんと勉強しないといけないなと分かりました。
個人的に未知の領域なので大変参考になりました。ありがとうございました :)

d(l)4

こんにちは。
RewriteCond %{HTTP_USER_AGENT} "Firefox\/3"
上記の記述ですけど、現在のバージョンFirefox/32とかなので、誤爆しますね。

1024jp @webmaster

> d(l)4 さん
おぉ、ご指摘ありがとうございます。
そうですね、確かに今もう ver. 3x だから引っかかりますね。
後で直しときます。

この記事へのコメント受付は終了しました。