ウェブサイトのグラフィック表現において SVG(Scalable Vector Graphics)は欠かせません。
この記事では SVG を使用するのに適したケースやメリットおよび、SVG の実装方法のパターン、SVG コードの最適化についてまとめます。
SVG に適したケース
見出し「SVG に適したケース」SVG はシンプルな構成で、境界線が明確な以下のタイプのグラフィックに適しています。
- ロゴ
- アイコンやピクトグラム
- イラスト
- チャート
イメージマップ
見出し「イメージマップ」かつては、イメージマップ(<map>
)と呼ばれる、画像上の特定のエリアにリンクを付与する実装が多く見られましたが、現在は SVG で実装できます。
以下は、よくある日本地図から各地域のページにリンクを付与する機能を SVG で実装したデモです。
リンクを無効にしているため、地域を選択してもページ遷移は発生しません。
SVG の仕様は膨大なためこの記事ではとても紹介しきれませんが、グラデーション、回転、フィルタ効果、クリッピング、マスキング、アニメーションなどさまざまな機能があり、表現の可能性はいくらでも広がります。
SVG のメリット
見出し「SVG のメリット」SVG を使用するメリットとしては、以下が考えられます。
- 拡大しても劣化しない
- ホバー効果やダークモードに対応しやすい
- 再利用しやすい
なお、ファイルサイズについては、次世代画像フォーマット(WebP や AVIF)と比較するとサイズが大きくなってしまう場合が多いです。
ただ、パフォーマンスの観点から考えると、SVG はインラインで表示することができるので、HTTP リクエストを減らせるというメリットも踏まえて評価するのがよいかもしれません。
拡大しても劣化しない
見出し「拡大しても劣化しない」SVG は文字どおりスケールできるベクター形式の図形なので、いくら拡大しても品質を維持することができます。
そのため、特にウェブサイトのロゴに使用するのに適しています。
ホバー効果やダークモードに対応しやすい
見出し「ホバー効果やダークモードに対応しやすい」インライン SVG で実装する場合、CSS から fill
の値を変更してカラーを変更したり、transform
で一部のパーツを動かしたり変形することができます。また、<use>
要素で参照する方法でも、全体のカラー(fill
)を変更することができます。
これにより、ホバー効果を付けたり、ダークモードを導入するのが容易になります。
なお、「リニューアル振り返り - CSS 編」でも言及しましたが、このとき currentColor
キーワードを使用することで柔軟性が高くなります。
以下の例では currentColor
によって、ボタンに指定してる color: #cfdddd
が、SVG アイコンにも反映されますが、ホバーで変更したカラーもそのまま反映されます。
再利用しやすい
見出し「再利用しやすい」JPEG などのビットマップ形式の場合には、一度書き出した後に調整できることは限られますが、ベクター形式の SVG であれば、書き出した後のファイルをそのままデザインツールで開いて、品質を損なうことなく調整することができます。
また、SVG はテキストベースのため、カラー変更レベルであれば、デザインツールからファイルを開かなくても、直接エディタからコードを調整することもできます。
SVG の実装方法
見出し「SVG の実装方法」SVG をウェブサイトで表示させるには、大別すると以下の実装方法が考えられます。
- インライン SVG
<img>
<use>
- 背景画像(
background-image
)
実装方法によって、CSS や JS を使用して SVG を操作できるか、外部ファイルを参照できるかどうかが異なるので、用途や制約によって使い分けます。
実装方法 | CSS 操作 | JS 操作 | 参照 |
---|---|---|---|
1. インライン | ✅ 対応 | ✅ 対応 | 内部 |
2. <img> | - | - | 外部 |
3. <use> | 一部対応 | - | 内部 / 外部 |
4. 背景画像 | - | - | 内部 / 外部 |
1. インライン SVG
見出し「1. インライン SVG」HTML に直接 SVG のコードを指定する方法で、もっとも一般的です。
CSS、JS での操作ができ、パフォーマンスも高いため、コンポーネントとして一元管理できるといった場合など、メンテナンス性に問題がなければ、まずはこの方法を採用します。
SVG 内の各要素にアニメーションをつけることもできるため、イラスト内のパーツを個別に動かしたい場合にも適しています。
2. <img>
見出し「2. <img>」通常の画像と同じように、SVG 形式で書き出した画像ファイルを <img src="...">
で読み込む方法です。
他の画像ファイルと同じく外部ファイルとして管理できるので、メンテナンス性は高いですが、CSS や JS で直接操作ができないため、そのようなニーズがあるときには他のアプローチを取る必要があります。
また、この方法では HTTP リクエストが発生するため、インライン SVG などと比較するとパフォーマンスコストがかかります。
3. <use>
見出し「3. <use>」<use>
要素を使用することで、ファイルの内部または外部から SVG を参照することができます。
以下は外部の SVG ファイル(icon-arrow.svg
)に id
属性を付与しておき、<use>
要素で参照する方法です。
外部の SVG ファイルで管理したいが、ホバー効果などで CSS の操作を加えたいときに使える手法です。
ただ、CSS で変更できるのは SVG 全体のスタイルになるので、パーツごとに変化を加えたい場合には、インライン SVG で実装する必要があります。
SVG スプライト
見出し「SVG スプライト」複数のアイコンを一箇所にまとめておき、使いたいアイコンを抜き出す方法として知られる SVG スプライトも、<use>
要素を使用した手法です。
以下は HTML 内に <symbol>
を記述しておき、<use>
で参照する例です。
4. 背景画像
見出し「4. 背景画像」CSS の background-image
で指定する方法で、HTML に SVG のコードを記述できない制約があるときに用います。
外部ファイルを参照するのが一般的ですが、Data URL で直接コードを指定することもでき、この場合には HTTP リクエストが発生しないので、パフォーマンスに優れています。
SVG コードの最適化
見出し「SVG コードの最適化」デザインデータの調整
見出し「デザインデータの調整」SVG を画像として用いる場合には、オブジェクトの線やテキスト要素をあらかじめアウトライン化しておき、ブラウザで表示したときに見た目が変わらないようにします。
次に、Illustrator のパスファインダの「合体」「型抜き」「交差」といった機能を使用して、オブジェクトの形状をなるべくシンプルにして、コードの量を抑えます。
Figma のパスファインダに相当する機能(「Union」「Subtract」など)でも調整できますが、Illustrator を使ったほうが無駄のないシンプルなパスに仕上がります。
加えて、可能であればパス上の不要なアンカーポイントを削除しておきます。
不要なコードの削除
見出し「不要なコードの削除」デザインツールで書き出した SVG のコードには不要なコードが含まれることがあるので、「SVGO」のようなツールで取り除くか、直接コードから削除します。
- XML 宣言(
<?xml version="1.0" encoding="utf-8"?>
) - ジェネレータのコメント(
<!-- Generator: Adobe Illusrator... -->
) <svg>
のversion
、xmlns:xlink
、xml:space
といった属性- 不要な
<g>
要素 - 不要な
id
属性やdata-name
属性 - 別途 CSS でスタイルを指定するときの
<style>
要素やclass
、fill
の属性
- インライン SVG の場合には
xmlns="http://www.w3.org/2000/svg"
の指定も省略できます。 <svg>
のviewBox
属性や、width
height
属性を省略できる場合もありますが、ケースバイケースで慎重さが求められるので、無理に省略しなくてもよいでしょう。
以下は Illustrator の「別名で保存」で書き出したコードを最適化する例ですが、ファイルサイズを 735 byte から 344 byte まで削減することができます。
単体で見ると削減できるサイズは小さいですが、SVG はロゴやアイコンのようにサイト共通の要素として使用することが多いので、これらの積み重ねによってパフォーマンス改善に貢献することができます。
SVG は厳格な言語
見出し「SVG は厳格な言語」SVG は XML ベースの言語のため、HTML と比較すると厳格な文法が求められます。
例えば、要素の終了タグは必須で、<path>
要素などの空要素に対しても必ずスラッシュ(/
)で閉じる必要があり、これらを遵守しないとエラーが発生して正しく表示されなくなります。
また、<svg>
要素内で使用できる要素も限定されているので、使用できない要素で囲うとその要素は表示されなくなります。
そのほかにも、大文字と小文字を区別する、属性値の引用符を省略できないといった構文規則があります。
直接コードを調整する際には、これらの点に注意する必要があります。
アクセシビリティの確保
見出し「アクセシビリティの確保」SVG の暗黙のロールは role="graphics-document"
です。
インライン SVG で画像として実装する場合には、アクセシビリティを確保するために role="img"
と <title>
要素(もしくは aria-label
属性)を指定します。
SVGO のような圧縮ツールを使用する場合、これらの必要な指定が削除されることがありますので、適宜ツールの設定を調整する必要があります。
(SVGO のデフォルトは removeTitle: true
なので <title>
が削除されます)
さらなる最適化
見出し「さらなる最適化」アイコンやピクトグラムのようなシンボルには role="img"
のサブクラスである role="graphics-symbol"
を指定するのがより適切ですが、その判断が難しい場合もあるので、メンテナンス性や作業コストを考慮して採用するかを判断するとよいでしょう。
指定する際には、支援技術が role="graphics-symbol"
を認識しないケースを考慮して、role="graphics-symbol img"
とフォールバックの指定を加えるのがよいかもしれません。
そのほかにも、<svg>
に aria-labelledby
を付与して <title>
と紐づけたり、<desc>
要素で概要テキストを指定したりといった最適化が考えられますが、id
はページ内で一意でなければならないので、メンテナンスコストも作業コストも高くなります。
加えて、値が正しく設定されているかを検証するコストも高くなるので、ここまで対応できるケースは限られるかもしれません。
なお、SVG のアクセシビリティについては、以下の記事やドキュメントを参考にしました。