SVG アイコンの使い方:HTML・CSS・React・Vue
更新日 · 7 分で読めます
SVG アイコンは小さなベクターファイルです。どのサイズでもくっきり表示され、容量は数百バイトほどで、CSS で色も変えられます。ページに配置する方法は主に 4 つあります。どれを選ぶかは、アイコンにスタイルを当てる必要があるか、ページにいくつアイコンがあるか、どのフレームワークを使っているかで決まります。
1. <img> タグで SVG を読み込む
いちばん簡単な方法は、アイコンをほかの画像と同じように扱うことです。Iconyz のアイコンにはすべて公開 SVG URL があり、アイコンパネルに表示されます。
<img src="https://iconyz.com/api/public/svg/lucide/house.svg"
width="24" height="24" alt="ホーム">ファイルはブラウザにキャッシュされ、アイコンが HTML の描画を妨げることもありません。欠点は、CSS が画像の内部に届かないため、color や :hover のスタイルが効かないことです。単色アイコンなら、URL で色を指定できます。?color=%23e11d48(#e11d48 を URL エンコードしたもの)を付けてください。詳しくは SVG API ガイド をご覧ください。
本番のアプリでは、SVG をダウンロードして自分のサイトから配信することも検討してください。ページが外部の URL に依存しなくなります。
2. SVG をインラインで貼り付ける
アイコンを開いて SVG を選び、コードをそのまま HTML に貼り付けます。
<button class="btn">
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24"
aria-hidden="true">
<path fill="none" stroke="currentColor" stroke-width="2" d="…"/>
</svg>
ホーム
</button>インライン SVG はページの一部なので、色、サイズ、ホバー時の状態、トランジション、さらには個々のパスまで CSS で自由に制御できます。単色のセットは currentColor を使っているため、アイコンは親要素の文字色を自動的に引き継ぎます。最も柔軟な方法で、追加の HTTP リクエストも発生しません。
代わりに HTML のサイズが増えます。インラインのアイコンは、使うページごとにパスのデータが追加されます。長い表などで同じアイコンを何百回も繰り返す場合は影響が大きくなります。
3. CSS からアイコンを使う
CSS マスクを使うと、単色の SVG を background-color で塗りつぶした形に変えられます。マークアップを HTML に書かずに、アイコンを文字色に合わせられます。
.icon-home {
display: inline-block;
width: 1em;
height: 1em;
background-color: currentColor;
-webkit-mask: url("https://iconyz.com/api/public/svg/lucide/house.svg") no-repeat center / contain;
mask: url("https://iconyz.com/api/public/svg/lucide/house.svg") no-repeat center / contain;
}<span class="icon-home" aria-hidden="true"></span>アイコンパネルの CSS タブでは、SVG をデータ URI として埋め込んだこのルールを生成できるので、外部へのリクエストなしで動作します。マスクは単色アイコン専用です。マスクは形だけを残し、アイコン自体の色は捨ててしまいます。マルチカラーのアイコンには background-image を使ってください。
4. React など JSX のフレームワーク
JSX では属性をキャメルケース(stroke-width ではなく strokeWidth)で書き、props をそのまま渡します。アイコンパネルの React タブで、すぐに使えるコンポーネントを生成できます。
export function HouseIcon(props) {
return (
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em"
viewBox="0 0 24 24" {...props}>
<path fill="none" stroke="currentColor" strokeWidth={2} d="…" />
</svg>
);
}
// 使い方
<HouseIcon className="text-blue-600" style={{ fontSize: 20 }} aria-hidden="true" />サイズが 1em なので、アイコンは font-size に合わせて拡大・縮小します。色が currentColor なので、Tailwind の text-* などのユーティリティクラスで色を変えられます。アイコンは 1 ファイルに 1 つにするか、モジュールにまとめておくと、バンドラーが使っていないアイコンを除去(ツリーシェイキング)できます。同じコンポーネントは Preact でも動き、Solid タブでは Solid 版を取得できます。
5. Vue と Svelte
Vue では、アイコンを単一ファイルコンポーネントとして保存します。class など渡した属性は、ルートの <svg> に引き継がれます。
<!-- HouseIcon.vue -->
<template>
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24">
<path fill="none" stroke="currentColor" stroke-width="2" d="…" />
</svg>
</template>Svelte も同じで、ルート要素に {...$$props} を付けた SVG マークアップを .svelte ファイルに書きます。どちらもアイコンパネルのタブから取得できます。
サイズと色
- サイズは
1emで指定。幅と高さを1emにすると、アイコンが隣のテキストと同じ大きさになります。サイズはfont-sizeで変えます。 - viewBox は残す。
viewBoxは図形の座標系を決めるものです。削除すると拡大・縮小が崩れるので、サイズは幅と高さで変えてください。 - グリッドに合わせる。24px グリッドで描かれたアイコンは、24px や 48px などの倍数で最もくっきり表示されます。18px や 20px では、細い線が少しぼやけることがあります。
- 単色アイコンの色は
colorで。currentColorを使えば、通常時・ホバー時・ダークモードを 1 つの CSS ルールで扱えます。 - マルチカラーのアイコンは元の配色を保つ。絵文字、国旗、ロゴには色が組み込まれています。色を変えるのはライセンスが改変を認めている場合だけにし、ブランドロゴは絶対に改変しないでください。
アクセシビリティ
まず、アイコンが意味を持つかどうかを判断します。テキストラベルの横にある装飾用のアイコンはスクリーンリーダーから隠し、アイコンだけで意味を伝える場合は代替テキストを用意します。
<!-- 装飾用: ボタンにはすでにテキストがある -->
<button><svg aria-hidden="true" …>…</svg> 保存</button>
<!-- アイコンだけのボタン: ボタンにラベルを付け、アイコンは隠す -->
<button aria-label="閉じる"><svg aria-hidden="true" …>…</svg></button>
<!-- 意味のある画像 -->
<img src="…/triangle-alert.svg" alt="警告">コントラストも確認しましょう。WCAG 2.2 では、情報を伝えるアイコンは背景とのコントラスト比が 3:1 以上必要です。
どの方法を選ぶべき?
| 方法 | CSS でのスタイル | 追加リクエスト | 向いている用途 |
|---|---|---|---|
| <img> | 不可(色は URL で指定) | あり(キャッシュされる) | コンテンツ内の画像、メール、Markdown、手早いプロトタイプ |
| インライン SVG | 自由自在 | なし | ホバーやアニメーションが必要な少数のアイコン |
| CSS マスク | 色とサイズ | データ URI ならなし | CSS 中心のサイトやデザインシステムのアイコンクラス |
| コンポーネント | 自由自在 | なし(バンドルされる) | React、Vue、Svelte、Solid のアプリ |
さっそく始めましょう。すべてのアイコンセットを検索するか、Lucide、Tabler Icons、Material Design Icons などの人気セットを見てみてください。公開する前にセットのライセンスを確認しましょう。アイコンのライセンスガイドで、それぞれの条件を解説しています。