SVG Symbol

フォントベースのアイコンの代替手段——SVG シンボルスプライトを使用して、スケーラブルなマルチカラーアイコンを HTML に直接埋め込む方法です。

SVG シンボルスプライトとは?

SVG シンボルスプライトは、複数の SVG アイコンを 1 つのファイルにまとめます。各アイコンはユニークな id を持つ <symbol> 要素内に定義されます。アイコンを使用するには、<use href="#icon-id"> で参照します。スプライトは一度だけロードされ——インラインか外部ファイルとして——個々のアイコンはページのどこでもレンダリングできます。

これはアイコンフォントとは根本的に異なるアプローチです。Unicode コードポイントをフォントグリフにマッピングする代わりに、ネイティブの SVG 要素を使用します。各アイコンはフル SVG の能力を保持しています:複数の色、グラデーション、フィルター、きめ細かいアクセシビリティ属性。トレードオフは、フォントアイコンの純粋な CSS アプローチと比べて、マークアップとスタイリングの規則が若干複雑になることです。

仕組み

スプライトファイルは、1 つ以上の <symbol> 要素を含む通常の SVG ドキュメントです。各シンボルは独自の viewBox を持つ自己完結したアイコンを定義します:

icons.svg(スプライトファイル)
<svg xmlns="http://www.w3.org/2000/svg" style="display:none">
  <symbol id="icon-home" viewBox="0 0 24 24">
    <path d="M3 12l9-9 9 9M5 10v10a1 1 0 001 1h3a1 1 0 001-1v-4..."/>
  </symbol>
  <symbol id="icon-search" viewBox="0 0 24 24">
    <path d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"/>
  </symbol>
</svg>

外側の <svg>style="display:none" で非表示にし、ページ上のスペースを取りません。内部のシンボルは参照されるまで見えません。アイコンをレンダリングするには、<use> 要素を使用します:

HTML でシンボルを使用する
<svg class="icon"><use href="#icon-home"></use></svg>
<svg class="icon"><use href="#icon-search"></use></svg>

フォントベースの color プロパティの代わりに、fillstroke を使って CSS でアイコンをスタイリングします:

SVG アイコンの CSS
.icon {
  width: 24px;
  height: 24px;
  fill: currentColor;
  stroke: none;
}

fill: currentColor を使うことで、フォントアイコンが color プロパティで機能するのと同様に、アイコンが親要素のテキスト色を継承できます。

シンボルとフォントアイコンの比較

    シンボルのメリット
  • マルチカラーサポート——各パスが独自の fill と stroke を持てる
  • 各アイコンが本物の SVG 要素でアクセシビリティが優れる
  • Unicode マッピング不要——読みやすい名前でアイコンを参照
  • シャープなレンダリング——フォントヒンティングの問題やサブピクセルアーティファクトなし
  • アイコンの各パーツを独立してアニメーション可能
  • SVG の全機能に対応:グラデーション、フィルター、クリップパス、マスク
    シンボルのデメリット
  • より冗長なマークアップ(<svg><use> vs <i class="icon">
  • CSS の color でスタイリングしにくい——fill/stroke が必要
  • 外部スプライトはクロスオリジン読み込みで CORS の問題がある
  • 圧縮フォント形式より総ファイルサイズが大きい
  • アイコン使用ごとの HTML の重さが増す
  • ::before/::after 疑似要素のサポートなし

読み込み戦略

SVG シンボルスプライトをページに読み込む主な方法は 3 つあり、それぞれトレードオフがあります:

インラインスプライト

スプライット SVG 全体を HTML の <body> に直接貼り付けます。これが最もシンプルなアプローチです——CORS の問題なし、追加の HTTP リクエストなし。シンボルはページ上の任意の <use> 参照にすぐに利用できます。シングルページアプリや小さなアイコンセット(50 アイコン未満)に最適です。

外部スプライト

<use href="icons.svg#home"> で外部ファイルとしてスプライトを読み込みます。HTML をクリーンに保ち、ブラウザがスプライトをページとは独立してキャッシュできます。ただし CORS の問題があります:スプライトは同一オリジンから提供するか、サーバーが適切な Access-Control-Allow-Origin ヘッダーを設定する必要があります。Internet Explorer は外部の <use> 参照をサポートしていないため、IE サポートが必要な場合は svg4everybody ポリフィルを使用してください。

JS インジェクション

fetch() でスプライトファイルを読み込み、実行時に DOM に挿入します。これは外部スプライトのキャッシュ可能性とインラインスプライトの信頼性を組み合わせます——挿入された SVG はドキュメントの一部になるため、<use> 参照は CORS 制限なく機能します。Bobcorn はこのアプローチを生成します:ロード時にすべてのシンボルをフェッチして登録する JS ファイルです。

JS インジェクションアプローチ(Bobcorn の出力)
<!-- 生成された JS スプライトを読み込む -->
<script src="icons-symbol.js"></script>

<!-- 通常通りに使用: -->
<svg class="icon"><use href="#icon-home"></use></svg>
<svg class="icon"><use href="#icon-search"></use></svg>

JS ファイルはすべての <symbol> 定義を含む非表示の <svg> 要素を作成し、ドキュメントの body に追加します。ロード後、アイコンの参照方法はインラインアプローチと同一です。

SVG シンボルを使う場面

プロジェクトがフォントアイコンでは提供できない機能を必要とする場合、SVG シンボルスプライトが適切な選択です:

  • マルチカラーアイコン——アイコンが複数の色、グラデーション、単一グリフのフォントで表現できない複雑な塗りを使用する場合
  • アクセシビリティが最優先事項——各アイコンに <title> 要素と aria-label 属性を含め、スクリーンリーダーに意味のある説明を提供できる
  • アイコンパーツのアニメーション——アイコン内の個々のパスやグループをアニメーションする必要がある場合(例:設定アイコン内の回転するギア)
  • SVG を多用するプロジェクト——アプリケーションがすでにインライン SVG を広く使用しており、シンボルが既存のアーキテクチャに自然にフィットする
  • 最高のレンダリング鮮明度——フォントヒンティングが小さいサイズで配置の問題を引き起こす可能性があります。SVG シンボルはどのサイズでもピクセルパーフェクトにレンダリングします

フォントアイコンを使い続ける場面

いくつかの一般的なシナリオではフォントアイコンの方が優れた選択です:

  • 大型アイコンセット(200 以上)——圧縮された WOFF2 フォントファイルは同じ数のアイコンを持つ SVG スプライトよりも大幅に小さい
  • すべてモノクロのアイコン——すべてのアイコンが単色の場合、フォントアイコンはトレードオフなく最もシンプルな統合を提供する
  • CSS のみの統合——フォントアイコンはスタイルシートリンクと CSS クラスだけでよく、JavaScript や追加マークアップが不要
  • レガシーシステム——すでにアイコンフォントを使用しているプロジェクトは、切り替えを正当化するほどの利益が得られない
  • 疑似要素のサポート——フォントグリフでしか機能しない ::before または ::after 疑似要素にアイコンが必要な場合
Bobcorn での使用
Bobcorn はフォントファイルと並んで、JS シンボルスプライトファイルとしてアイコンをエクスポートできます。エクスポートダイアログで JS オプションを有効にしてください。生成されるファイルはロード時にインライン SVG スプライトを作成してすべてのシンボルを登録します。同じプロジェクトで両方のアプローチを使用できます——シンプルな UI アイコンにはフォント、複雑なカラーイラストレーションにはシンボルというように。
ヒント
どちらか一方を選ぶ必要はありません。多くのデザインシステムは大量のモノクロ UI アイコン(ボタン、ナビゲーション、フォーム要素)にフォントアイコンを使用し、少数のマルチカラーイラストレーションやアニメーションアイコンに SVG シンボルを使用しています。Bobcorn のエクスポートダイアログでは、1 回のエクスポートで両方を生成できます。