はじめに
アイコンライブラリを選ぶとき、「フォントアイコンを使うか、SVGを直接使うか」で迷ったことはないでしょうか。フォントアイコンは手軽な反面、1文字だけ読み込みが遅れて四角が表示されたり、アクセシビリティ対応が面倒だったりします。かといって、必要なSVGを1つずつ探してきてviewBoxやスタイルを揃えるのも地味に手間がかかります。
Featherは、この悩みに「線の太さを統一した287種類のSVGアイコンを、1つのAPIで貼り付けるだけ」というシンプルな回答を出したライブラリです。GitHubで26,000以上のスターを集めており、stroke="currentColor"で描かれた24x24グリッドのアイコンは、CSSのcolorを変えるだけで色が揃います。
とはいえ、説明より動かした方が早いと思います。アイコン名・色・サイズを切り替えながらfeather.iconsのSVGがその場で変わるサンプルを用意しました。先に挙動を見たい方はこちらからどうぞ。
Featherとは
Featherは、Cole Bemisが開発した「Simply beautiful open source icons」を謳うSVGアイコンライブラリです。すべてのアイコンが24x24のグリッド上に、線の太さ・角の丸み・カラー方針を統一して設計されているため、どのアイコンを組み合わせても見た目がぶれません。MITライセンスで公開されており、npmパッケージのfeather-iconsはNode.js・ブラウザどちらでも利用できます。
主な特徴
- 287種類のSVGアイコン - すべて
strokeベースの線画スタイルで統一されており、混在させても違和感がない data-feather属性 +feather.replace()- HTMLにプレースホルダーを置くだけで、SVGへの一括変換が完了するtoSvg()によるSVG文字列生成 - JavaScriptから直接SVGマークアップを組み立てられるため、動的な一覧表示にも向くcurrentColorでの配色 - CSSのcolorプロパティを継承するので、アイコンの色をCSSだけで制御できる- SVGスプライト対応 -
dist/feather-sprite.svgを1つ読み込めば、<use>タグで参照する軽量な使い方もできる
インストール
npmでインストールする場合です。
npm install feather-icons
インストール不要でCDNから直接読み込むこともできます。
<script src="https://unpkg.com/feather-icons"></script>
Featherのサンプルを動かす
以下は、feather.icons[名前].toSvg()を使ってアイコン名・色・サイズを動的に切り替えるサンプルです。セレクトボックスでアイコンを選び、カラーピッカーとスライダーを動かすと、その場でSVGが再生成されます。
要点だけを抜き出すとこうなります。feather.iconsはアイコン名をキーにしたオブジェクトで、各値のtoSvg(attrs)メソッドを呼ぶとSVG文字列がその場で得られます。
import feather from 'feather-icons'
// feather.icons はアイコン名がキーのオブジェクト
const svg = feather.icons['heart'].toSvg({
color: '#e63946',
width: 48,
height: 48,
'stroke-width': 2,
})
document.getElementById('holder').innerHTML = svg
実際に動かせるものが下です。アイコン名を切り替えたり、色・サイズを変更したりすると、その場でSVGが再描画されます。
feather.icons[name].toSvg()は呼ぶたびに新しいSVG文字列を返すだけなので、アイコン名・色・サイズのどれを変えても、既存のDOMを丸ごと差し替える形で反映しています。次の「基本的な使い方」では、このtoSvg()よりもよく使われる、HTML側にプレースホルダーを置く書き方を見ていきます。
基本的な使い方
Featherの最も基本的な使い方は、data-feather属性を持つ要素を用意し、feather.replace()を呼ぶことです。
<i data-feather="circle"></i>
<i data-feather="check-square"></i>
<script src="https://unpkg.com/feather-icons"></script>
<script>
feather.replace();
</script>
feather.replace()は、ページ内にあるdata-feather属性つきの要素をすべて探し出し、対応するSVGマークアップに置き換えます。<i>要素に付けた属性(classやstroke-widthなど)は、そのまま生成される<svg>タグにコピーされるため、CSSクラスでの見た目調整もそのまま使えます。
Node.js環境では、個別のアイコンから直接SVG文字列を取得できます。
const feather = require('feather-icons')
// 個別アイコンからSVG文字列を取得
const svg = feather.icons['check-circle'].toSvg();
実践的なユースケース
data-feather属性とreplace()でまとめてテーマ切り替えする
feather.replace()には、すべてのアイコンに適用するデフォルト属性をオブジェクトで渡せます。ライト・ダークのようなテーマ切り替えでアイコンの色や線の太さを一括変更したいときに便利です。
// replace()の引数に渡した属性は、すべてのdata-feather要素に適用される
feather.replace({
color: '#f1faee',
'stroke-width': 1.5,
width: 32,
height: 32,
});
下のサンプルでは、テーマ切り替えボタンを押すたびにfeather.replace()をデフォルト属性つきで呼び直し、複数アイコンの色・線の太さ・背景色を同時に切り替えています。
ポイントは、feather.replace()を呼び直す前にdata-featherのプレースホルダーを作り直している点です。一度SVGに変換された要素はdata-feather属性を持たないため、再変換するにはプレースホルダーごと作り直す必要があります。
要素ごとの属性でアイコンを個別カスタマイズする
一括のデフォルト属性だけでなく、<i data-feather="...">要素自身に付けた属性は、そのまま生成される<svg>タグにコピーされます。同じfeather.replace()の呼び出しの中でも、アイコンごとに色やサイズを変えたいときに使えます。
<!-- 要素側の属性がSVGタグにそのままコピーされる -->
<i data-feather="star" color="#f4a261" stroke-width="1"></i>
<i data-feather="star" color="#e76f51" stroke-width="3"></i>
下のサンプルでは、優先度リストの各行にstroke-widthとcolorをそれぞれ個別指定し、同じstarアイコンでも見た目を変えて表示しています。スライダーで線の太さを変えると、全行が連動して変わります。
feather.replace()自体には引数を渡していないのに、行ごとに色が異なる点に注目してください。要素側に書いたcolor属性が優先され、スライダーで動かすstroke-widthだけが3行に共通で反映されます。
toSvg()でアイコン名を検索してプレビューする
287種類もあると、目的のアイコン名を覚えきれないことがあります。feather.iconsはアイコン名をキーにしたオブジェクトなので、Object.keys(feather.icons)で全アイコン名を取得し、入力文字列で絞り込むプレビューUIが簡単に作れます。
// 全アイコン名を取得し、部分一致で絞り込む
const names = Object.keys(feather.icons)
const matched = names.filter((name) => name.includes(query))
下のサンプルでは、検索ボックスに入力するたびに一致するアイコン名を絞り込み、toSvg()でプレビューを再描画しています。「arrow」「file」のような単語で試してみてください。
検索欄を空にすると先頭12件、何か入力するとincludes()による部分一致でその場で絞り込まれます。toSvg()がアイコンごとに独立したSVG文字列を返すため、feather.replace()のようにDOM側の準備をせず、検索結果の数だけ動的に生成できるのがこのAPIの強みです。
まとめ
Featherは、287種類のSVGアイコンを「統一された線画スタイル」と「シンプルなAPI」で提供するアイコンライブラリです。
data-feather属性とfeather.replace()の組み合わせが、HTML中心の最も基本的な使い方feather.replace(attrs)にデフォルト属性を渡せば、テーマ切り替えのような一括変更ができる- 要素側に直接書いた属性(
colorやstroke-widthなど)は個別のSVGタグへそのままコピーされ、一括設定より優先される feather.icons[name].toSvg(attrs)を使えば、JavaScript側から動的にSVGを生成できる。検索・一覧表示のようなUIに向く
「アイコンごとにデザインがバラバラで統一感が出ない」と感じたら、まずは数個のアイコンをdata-feather属性で差し替えてみるところから試してみてください。
