外部 CSS ファイルにインラインで SVG を埋め込む方法


 別に style タグやインラインスタイルに書いてもいいけど。

 ということで、SVG ってあるじゃないですか。

 いわゆるひとつの、Scalable Vector Graphics。

 一般的に広く使われている JPEG や PNG のようなラスタイメージとは違ってベクタ形式なので、拡大縮小しても綺麗に表示できるっていうアレですね。

 SVG は XML――すなわちテキストで記述されているので、ラスタイメージのように画像自体の縦横に比例してファイルサイズが際限なく大きくなってしまうようなことが起こり難く、ファイルサイズを比較的小さく保ち易いという利点もあります。

※テキストだけに、http での転送時は gzip 圧縮も利きますし。

 綺麗な上にファイルサイズも小さいときては、最近の Web ブラウザは基本的に対応していることもあり、そろそろ積極的に使っていこうと考えている方も多いのではないかと思います。

 さて、そんな SVG ですが、個別のファイルとして用意する他に、HTML ファイル内に直接記述するという書き方も可能です。

 いわゆる、インライン SVG ですね。

 と、ここまでは常識的な話なのですが、場合によっては、外部 CSS ファイルに SVG を直接埋め込みたい場合もあるのではなかろうか、と。

 はて、その時は、どうやって書いたらええんじゃい、という点について、以下で見ていくことにします。

 それなりにレアなケースかと思いますが、どなたかのお役に立ちましたら。

 ちなみに、伝わり易さを優先して、タイトルではインラインという表現を使いましたが、この場合はどちらかというと embedded(埋め込み)の方が正しいと思います。

スポンサーリンク

読み込み中です。少々お待ち下さい

まずは普通のパターンから

 まずは、普通の書き方から見ていきましょう。

 インライン SVG の場合、例えば HTML 内に次のように記述します。

<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">   <style type="text/css">     .abox { fill: #ffd3e0; }     .aline { fill: none; stroke: #ffffff; stroke-width: 2; }   </style>   <rect class="abox" width="70" height="70" transform="translate(50) rotate(45)" />   <polyline class="aline" points="100,100 50,50 100,0" />   <polyline class="aline" points="0,0 50,50 0,100" /> </svg>
  • こんな感じで表示されます

 上のコードをそのまま argyle.svg というファイルに保存し、次のようにイメージのソースとして指定することも可能です。というか、通常はこの方法を使うことが多いでしょう。

<img src="argyle.svg" />

 さらに、こんな風にスタイルシートの background-image 等で指定することも可能です。

.argyle { background-image: url(argyle.svg); background-repeat: repeat; background-position: -50px -50px; background-color: #e0ffd3; }

 この他、object や embed などのタグを使って表示することも可能ですが、特殊な用途を除いてあまり使う機会はないでしょう。

外部 CSS に SVG を埋め込む

 さて、最後に挙げた CSS で指定する場合に、どうすれば SVG を直接で記述できるでしょうか。

 そうです。お察しの通り、SVG の場合も他の画像形式と同様に、 Data URI Scheme を使用して SVG のコードをそのまま base64 またはパーセントエンコード(URL エンコード)してあげれば良いようです。

 具体的には、例えば以下のように書きます。

base64 の場合

  background-image:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAiIGhlaWdodD0iMTAwIj48c3R5bGUgdHlwZT0idGV4dC9jc3MiPi5hYm94e2ZpbGw6I2ZmZDNlMDt9IC5hbGluZXtmaWxsOm5vbmU7c3Ryb2tlOiNmZmZmZmY7c3Ryb2tlLXdpZHRoOjI7fTwvc3R5bGU+PHJlY3QgY2xhc3M9ImFib3giIHdpZHRoPSI3MCIgaGVpZ2h0PSI3MCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNTApIHJvdGF0ZSg0NSkiLz48cG9seWxpbmUgY2xhc3M9ImFsaW5lIiBwb2ludHM9IjEwMCwxMDAgNTAsNTAgMTAwLDAiLz48cG9seWxpbmUgY2xhc3M9ImFsaW5lIiBwb2ludHM9IjAsMCA1MCw1MCAwLDEwMCIvPjwvc3ZnPg=="); /* 赤字部分が base64 でエンコードした SVG */

※先頭の「data:image/svg+xml;base64,PHN2Z...」のセミコロンやカンマを打ち間違えないように気をつけてください。

パーセントエンコードの場合

  background-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22100%22%20height%3D%22100%22%3E%3Cstyle%20type%3D%22text%2Fcss%22%3E.abox%7Bfill%3A%23ffd3e0%3B%7D%20.aline%7Bfill%3Anone%3Bstroke%3A%23ffffff%3Bstroke-width%3A2%3B%7D%3C%2Fstyle%3E%3Crect%20class%3D%22abox%22%20width%3D%2270%22%20height%3D%2270%22%20transform%3D%22translate(50)%20rotate(45)%22%2F%3E%3Cpolyline%20class%3D%22aline%22%20points%3D%22100%2C100%2050%2C50%20100%2C0%22%2F%3E%3Cpolyline%20class%3D%22aline%22%20points%3D%220%2C0%2050%2C50%200%2C100%22%2F%3E%3C%2Fsvg%3E"); /* 赤字部分がパーセントエンコードした SVG */

 冒頭にも書きましたが、別に外部 CSS でなく、style タグや各種タグの style 属性(インラインスタイル)で指定しても構いません。

 とはいえ、「エンコードすればいい、とか気軽に言うけどさー、一体どうやったらいいのさ」という向きもおありでしょう。

 どこかに、お手軽にエンコードできるツールでもあれば良いのですが。

 ......おや?

 こんなところに、貼り付けた文字列を色々とお手軽に変換できるツールがありますね?

 わぁ、base64 やパーセントエンコードも自由自在だぁ(棒

 ということで、手前味噌で恐縮ですが。

 テキストエリアに元の SVG コードを貼り付けて、パーセントエンコードの場合は「URL」→「encodeURIComponent」を、base64 の場合は「HTML」→「Base64エンコード」を選択すれば、簡単にエンコードできます。

 ちなみに、毎回この記事を開かずとも、こちらからツールを単体で利用できます。

 詳しい説明は、作った時に書いたこちらの記事を参照してください。

 いやー、これを作った時は、「テキストの base64 エンコードなんて、誰が使うねん」と自嘲したものですが、世の中何が役に立つか分からないものですね。

※このツールは単純な静的 HTML です。全ての処理はクライアント側だけで処理され、入力したテキストがサーバーに送られたりはしませんので、安心してご利用ください。

おわりに

 base64 でエンコードすると、SVG の内容を更新する度に再エンコードが必要になるので、その場で修正できる可能性が高いパーセントエンコードの方が、どちらかというと取り回しが楽かも知れません。

 パッと見の難読化は base64 の方が上ですけど、簡単にデコードできるので意味ないですしね。

 本格的に使うなら、埋め込み作業を自動化してしまった方が楽だと思います。

この記事をシェア
  • このエントリーをはてなブックマークに追加
  • Share on Google+
  • この記事についてツイート
  • この記事を Facebook でシェア