SVG Symbol
フォントベースのアイコンの代替手段——SVG シンボルスプライトを使用して、スケーラブルなマルチカラーアイコンを HTML に直接埋め込む方法です。
SVG シンボルスプライトとは?
SVG シンボルスプライトは、複数の SVG アイコンを 1 つのファイルにまとめます。各アイコンはユニークな id を持つ <symbol> 要素内に定義されます。アイコンを使用するには、<use href="#icon-id"> で参照します。スプライトは一度だけロードされ——インラインか外部ファイルとして——個々のアイコンはページのどこでもレンダリングできます。
これはアイコンフォントとは根本的に異なるアプローチです。Unicode コードポイントをフォントグリフにマッピングする代わりに、ネイティブの SVG 要素を使用します。各アイコンはフル SVG の能力を保持しています:複数の色、グラデーション、フィルター、きめ細かいアクセシビリティ属性。トレードオフは、フォントアイコンの純粋な CSS アプローチと比べて、マークアップとスタイリングの規則が若干複雑になることです。
仕組み
スプライトファイルは、1 つ以上の <symbol> 要素を含む通常の SVG ドキュメントです。各シンボルは独自の viewBox を持つ自己完結したアイコンを定義します:
<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> 要素を使用します:
<svg class="icon"><use href="#icon-home"></use></svg>
<svg class="icon"><use href="#icon-search"></use></svg>
フォントベースの color プロパティの代わりに、fill と stroke を使って 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 スプライトを読み込む -->
<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疑似要素にアイコンが必要な場合