SVG+CSSでWebサイトをリッチにしてみませんか?

こんにちは! pairs Global事業部の山内です。JavaScriptを書いています。


早速ですがこちらを御覧ください。

See the Pen svg-logo-pairs by yamauaa (@yamauaa) on CodePen.


こちらは「SVG(画像)」と「CSS」を用いた、弊社pairsロゴの線画アニメーションです。
※ GIFアニメじゃないです、JavaScriptも使っていません

もう少し頑張って、こんな表現もできます。

See the Pen svg-logo-eureka by yamauaa (@yamauaa) on CodePen.


当記事ではSVGの良いところを中心に、
「SVG+CSSアニメーション」についてご紹介したいと思います。
Webブラウザ上の表現手段として、SVGという選択肢が増えるきっかけとなれば幸いです。


忙しい人のための tl;dr

  • SVGは、XMLである(画像バイナリではない、文字列テキスト)
  • SVGは、どれだけ拡大しても描画がきれい(ベクタ形式の画像)
  • SVGは、XML要素をHTML/CSSと同じ感覚で操作できる
  • SVGは、CSSの知識があれば動かせるので学習コストが低い
  • SVGは、Illustratorから出力できる(デザイナーさんにお願いする)
  • SVGは、とても楽しい

SVGとは

平たく言うと、XML形式のテキストです。
線画の位置情報を、XMLの要素と属性で表現しています。

See the Pen svg-sample by yamauaa (@yamauaa) on CodePen.


↑ これがSVGです。
path , line 等の要素によって構成され、
d , x1 等の属性(位置情報)によって画像が描画されています。


SVGの使い方

SVGをブラウザで表示する手段はいくつかありますが、よく使われるのは以下の2つです。

  • IMGタグのソースとして描画
<img src="hoge.svg" />
  • SVGタグとして描画
<svg viewBox="">
  <path ....>
  <rect ....>
  <line ....>
</svg>

どちらも同じ内容がブラウザに表示されます。
当記事のトピック「SVG+CSSアニメーション」で利用するのは後者になります。


SVGの良いところ、ユースケース

SVGはベクタ形式の画像です。
ベクタ形式はどれだけ拡大してもきれいに描画され、ジャギることはありません。
(輪郭がギザギザにならない)

※ PNG画像など、拡縮で画像が劣化してしまう形式をラスタ形式といいます。

HTML/CSSと同じ感覚で操作できるので、低い学習コストでリッチなクリエイティブを実現できます。

逆に、写真など造形が複雑なクリエイティブには不向きです。
先に挙げたように、XML内に位置情報を持つことにより画像を描画するため、
画像が複雑であればあるほど、その位置情報は膨大な量になります。

ユースケースとしては

  • アイコンやロゴ等、単純な造形をしている場合
  • 大きく引き伸ばされて表示される可能性がある場合
  • 画像自体に動きをもたせることで、リッチ感やUXを向上させたいような場合

こういった状況では、SVGを検討する価値があります。

例えば、よくあるPNG画像のロゴアイコンについて、
『スマホレベルの拡縮であれば画像劣化も許容できそうだが、タブレットだとぼやけそう』
→ SVGならどれだけ拡大されてもきれいに描画できるので、SVGで実装しよう
という判断ができます。


Canvasとの違い

細かくは「グラフィックの描画プロセスが異なる」などありますが、明確に異なっているのは、

  • Canvasタグ内に、JavaScriptによって描画する
  • SVGタグ内に、XMLによって描画する

点です。ざっくりまとめると、

Canvas
  • すべてJavaScriptによって描画・動作する
  • 学習コスト高。可読性悪い
  • グラフィック系なんでもできる
SVG
  • CSSができれば、きれいなクリエイティブ実装が可能
  • (Canvasと比べれば)XMLなので可読性は良い
  • ただしCSSでできることに限る

といった違いがあります。(主観あり)


SVG+CSSで必要な、+α知識

CSSから操作するのは、SVG独自の属性です。
当記事のサンプルで使ったプロパティを紹介します。

  • stroke・・・線の色    eg.) stroke: #000
  • stroke-width・・・線の幅    eg.) stroke-width: 3
  • fill・・・塗りつぶしの色    eg.) fill: #fff
  • fill-opacity・・・塗りつぶしの透過度    eg.) fill-opacity: .5
  • stroke-dasharray・・・線の感覚    eg.) stroke-dasharray: 3000
  • stroke-dashoffset・・・線の位置    eg.) stroke-dashoffset: 3000

『べつにSVGじゃなくても良くない?』

本当にSVGに価値があるのか、もう少し具体的に考えてみようと思います。

例えば「3本線のメニューアイコンから×印へ変化するアニメーション」を実装するとします。

See the Pen svg-toggle by yamauaa (@yamauaa) on CodePen.



↑ このクリエイティブを、SVGを使わないで実装する手段を考えます。

「よし、自分でHTMLくんだろ!」
<div class="bar-top"></div>
<div class="bar-middle"></div>
<div class="bar-bottom"></div>
<div class="square"></div>
  • div要素を棒状にして…?
  • 大きさは?サイズ指定の値が小さいけど拡縮表示は大丈夫かな…
  • 棒のカドが角ばってる…border-radius?…
  • positionで配置して…
  • etc,etc…
  • orz
「ならば画像や!デザイナーさんPNG画像ちょうだい!」
<img src="icon_menu.png" />
  • …あ!動かせない
  • orz
「デザイナーさん全部ばらばらで!」
<img src="bar_top.png" />
<img src="bar_middle.png" />
<img src="bar_bottom.png" />
<img src="square.png" />
  • 配置するCSS書いて…
  • 配置が崩れないようにアニメーションさせて…
  • Android実機ブラウザで画像動かすの重いなカクカクする…(主観)
  • 拡大しても大丈夫かな…
  • あ、imgリクエストが4本増えた…
  • orz
…SVGなら
「デザイナーさん、メニューアイコンをSVG出力でお願いできますか?」
  • 既にDOM(XML)の配置が完成している
  • CSSを使って上下の棒を動かすだけ
  • 拡大してもジャギらない、描画が美しい

スマートですね、かんたんじゃない?


おわりに

今回ご紹介した「SVG+CSSアニメーション」というのは、
SVGを操作する手段の一つに過ぎず、
実はSVG自体にもアニメーションのAPIがあったりと、SVGは奥が深いです。

また、気持ちよく画像を動かすためには、
SVG出力の形(XML構成)がキモになるので、デザイナーさんの協力は必要不可欠です。
場合によっては、プログラマからXML構成を提案・依頼することが必要になると思います。

簡単と言いつつ、考慮する手間も多いSVGですが、
使っているアプリケーションが気持ちの良い動きをするというのはとても大切で、
ユーザーの『また使ってみよう』という心にきっと刺さると思っています(と信じています)。

SVGを使って、今あるWebサイトを少しだけリッチにしてみませんか?

  • このエントリーをはてなブックマークに追加

エウレカでは、一緒に働いていただける方を絶賛募集中です。募集中の職種はこちらからご確認ください!皆様のエントリーをお待ちしております!

Recommend

Camp Match 2016 @Dallas に参戦してきました!

pairsの検索機能をElasticsearchにリプレースした話