ブログ

SVG画像で作る汎用的で使い回しやすいアイコンポーネント

他のサイトのソースコードを眺めていて、「これいいな」と思ったアイコンコンポーネントの作成方法を紹介しています。この方法が便利すぎて最近のコーディングでは必ずと言っていいほど使用しています。

アイコンコンポーネントの作成例

早速ですが以下が作成例です。

index.html
<span class="c-icon" data-c-icon="home" aria-hidden="true"></span>
style.css
.c-icon {
display: block;
width: 100%;
}
.c-icon::before {
content: "";
width: 100%;
height: 100%;
background-color: currentcolor;
display: inline-block;
mask-position: center;
mask-repeat: no-repeat;
mask-size: contain;
}
.c-icon[data-c-icon="home"]::before {
aspect-ratio: 1;
mask-image: url(../img/common/icon_home.svg);
}

アイコンを表示する用のspanタグを用意し、アイコン自体はspanタグの擬似要素で出力しています。

使い方

例えば矢印のアイコンを表示したい場合には、HTMLの表示したい箇所に以下のように記述します。data-c-icon="アイコン名"の箇所で、表示するアイコンを指定します。

index.html
<span class="c-icon" data-c-icon="arrow" aria-hidden="true"></span>

CSSでは上記のベースとなる記述に加えて、矢印に関連するコードを追加します。

style.css
.c-icon[data-c-icon="arrow"]::before {
aspect-ratio: 18 / 20; // アイコンの縦横比を記述
mask-image: url(../img/common/icon_arrow.svg); // アイコン画像へのパスを記述
}

表示したいアイコンの種類が増えた場合には、CSSにその都度コードを追加するイメージです。基本的にはアイコンごとにaspect-ratiomask-imageを追加してあげれば機能するかと思います。

ラッパー要素で囲ってあげて、親要素側でアイコンのサイズを管理すると汎用性が高まります。

index.html
<div class="arrow-icon">
<span class="c-icon" data-c-icon="arrow" aria-hidden="true"></span>
</div>
style.css
.arrow-icon {
width: 50px;
}
アイコンコンポーネントの表示例

メリット

SVG要素をCSSで出力するアイコンコンポーネントの作成方法は、特定の状況で非常に効果的で、以下のような利点があると考えています。

メンテナンス性の向上

アイコンの追加・変更が.c-icon[data-c-icon="アイコン名"]のパターンで統一的に行えるため、保守・管理が行いやすくなります。またSVGのパスを直接HTMLに書く場合と比べて、HTMLがシンプルに保たれ、可読性が向上します。

柔軟な拡張性

currentcolorを使用することで、色を親要素やスタイルのコンテキストに従わせることができます。hover時の色変更のアニメーションやダークモード対応など、柔軟性が高まります。

ファイルサイズの最適化

SVGファイルを外部化することで、同じアイコンが複数箇所で使用される場合でもキャッシュを活用することが可能です。またHTMLにSVG画像をインラインで記述する場合と比べて、HTMLのファイルサイズを小さく保つことができます(どの程度効果があるかは疑問)。

まとめ

メリットの多い方法なので今後も積極的に活用していこうと思います。SASSで_c-icon.scssファイルを作成し基本的なコードを記述しておけば、多くのプロジェクトにおいて使えそうです。

ただし、一部のレガシーブラウザではmask-imageがサポートされていない場合があるのと、複雑なマルチカラーのSVGにはこの方法は適していないので注意が必要です(mask-imagebackground-imageに変更することで表示は可能です)。