React.jsでFont-Awesome 6を使う方法
はじめに
Font AwesomeはWebページやアプリなどに使えるアイコンを提供しているサービスです。無料版でもかなりの種類のアイコンがあるので、利用されている方も多いと思います。
このページ右側のサイド・バー(スマートフォンでご覧の場合はページ下部)にある、作者情報内のアイコンもFont Awesomeのものです。
今までは、Web Fonts + CSS形式で利用していましたが、使っていないアイコンのCSSまでブラウザに読み込まれてしまっていました。
今回、このサイトで利用しているアイコン全てを、公式が提供しているReact.js用のパッケージを利用する形式に切り替え、不要なCSSが読み込まれないように修正しました。
このパッケージの利用方法と、使うメリットについて解説します。
内容
Font Awesomeが公式に提供しているパッケージ(@fortawesome/react-fortawesome)の使い方を解説します。
Set Up with Reactを簡略化した内容となります。
なお、公式ページはkitを使う方法をやたらと進めてきますが、今回紹介する方法は、kitの利用はしません。
前提
Font Awesomeのバージョン
Font-Awesome 6.4を利用します。なお、無料版を前提とします。
環境
React.jsもしくは、React.js関連のフレームワーク(Next.js等)を利用していることが前提になります。
ちなみに、私の環境は以下のとおり、Next.js 13を利用しています。なお、新機能のApp Routerではなく、従来のPagesを利用しています。
"react": "^18.2.0",
"react-dom": "^18.2.0",
"next": "^13.4.1"
ブラウザ
今回説明するパッケージは、Web Fonts + CSSの形式のアイコンではなく、SVGのアイコンとなります。SVGをサポートしていない古いブラウザで動かす場合、利用できません。
公式パッケージを使うメリット
パフォーマンス
使うアイコンだけimportできるので、不要なCSSのダウンロードをなくすことができます。そのためパフォーマンス面で有利になります。
例えば、従来のWeb Fonts + CSS方式でアイコンを使うと、以下のようにlinkタグにCSSのリンクを設定することになります。実際に私が利用していたコードです。
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"></link>
CSSのリンクはClordFlareにあるものを利用していました。これはリンク全てのアイコンのCSSが入っているので、サイズも18kバイト近くあります。アイコンを1つ2つ使うだけなら、だいぶ無駄が出てしまいます。
ちなみに、Google Search Consoleでこのサイトのトップページをテストしてみたところ、モバイルでのパフォーマンスの評価で、このCSSの読込がレンダリングを2秒弱妨げていると指摘されました。
公式パッケージを使うことでこの問題も解決できそうです。
animation
アイコンを点滅させたり、回転させたり等、シンプルなanimationは簡単に実装できます。パッケージのFontAwesomeIconコンポーネントのspinやfadeといったプロパティを指定するだけです。
通常ならCSSのanimationの記述が必要ですが、その手間が省けます。
使い方
パッケージのインストール
インストールするものが結構あります。いずれも、パッケージ名が「fontawesome」でなく「fortawesome」になっていますが、合ってます。
coreのパッケージをインストール
これを直接importすることはありません。内部的にSVGを操ってくれるJavascriptだと思います。
npm i --save @fortawesome/fontawesome-svg-core
アイコンのsvgをインストール
使う種類ごとにインストールします。私は以下を入れました。いずれも無料で使えるアイコンです。
npm i --save @fortawesome/free-solid-svg-icons
npm i --save @fortawesome/free-regular-svg-icons
npm i --save @fortawesome/free-brands-svg-icons
Reactのコンポーネントをインストール
npm i --save @fortawesome/react-fontawesome@latest
コンポーネント作成
試しにTwitterのアイコンを表示してみます。
// React用のコンポをimport
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
// 利用するアイコンをimport。
// Twitterのような企業ロゴはbrandsにあります。
import { faTwitter } from "@fortawesome/free-brands-svg-icons"
export default function TwitterIcon() {
// FontAwesomeIconのiconプロパティに
// importしたアイコンを指定すればOK
return (
<FontAwesomeIcon icon={faTwitter} />
);
}
使いたいiconをimportして、FontAwesomeIconコンポーネントのiconプロパティに指定するだけです。簡単ですね!
SVGタグ
実際に生成されるSVGは以下のようになっていました。
<svg
aria-hidden="true" focusable="false"
data-prefix="fab" data-icon="twitter"
class="svg-inline--fa fa-twitter "
role="img"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
>
<path
fill="currentColor"
d="M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z">
</path>
</svg>
styleの適用
FontAwesomeのプロパティで、アイコンの大きさを指定したり、色を変えたり、回転させたりすることができます。また、CSSで指定することも可能です。
ここでいくつか見てみます。指定可能なプロパティの一覧は、ドキュメントをご確認ください。
// React用のコンポをimport
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
// 利用するアイコンをimport。
// Twitterのような企業ロゴはbrandsにあります。
import { faTwitter } from "@fortawesome/free-brands-svg-icons"
export default function TwitterIcon() {
return (
<div style={{ padding: "1rem", height: "100vh", backgroundColor: "#c1c1c1" }}>
<div>
デフォルト:
<FontAwesomeIcon icon={faTwitter} />
</div>
<div>
サイズ3倍・色変更:
<FontAwesomeIcon icon={faTwitter} size="3x" color="purple" />
</div>
<div>
90度回転:
<FontAwesomeIcon icon={faTwitter} rotation={90} size="2x" color="green" />
</div>
<div>
ボーダーと反転:
<FontAwesomeIcon icon={faTwitter} border inverse size="2x" />
</div>
<div>
CSSでサイズとか設定:
<FontAwesomeIcon
icon={faTwitter}
style={{
width: "80px", height: "80px",
color: "blue", marginLeft: "1rem"
}}
/>
</div>
</div>
);
}
- sizeプロパティ: サイズ変更。"1x"や"2x"のように、cssのfont-sizeの何倍かで指定
- colorプロパティ: 色を変更
- borderプロパティ: 枠線を表示
- invertプロパティ: 反転
なお、CSS等でwidthやheightを設定する場合、svgタグに対して設定されます。画像のように縦横比を変えることはできず、svgタグの大きさに合わせて、元の比率で表示されます。
実際にブラウザで見ると、以下のように表示されます。
animationの適用
せっかくなのでanimationの例も見ていきます。spinやfade等のプロパティを指定するだけです。beat、beatFade、bounce、fade、flip、shake、 spin、spin spinReverse、spinPulseの指定ができます。
いくつか試してみます。
// React用のコンポをimport
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
// 利用するアイコンをimport。
// Twitterのような企業ロゴはbrandsにあります。
import { faTwitter } from "@fortawesome/free-brands-svg-icons"
export default function TwitterIcon() {
return (
<div style={{ padding: "1rem", height: "100vh", backgroundColor: "#c1c1c1" }}>
<div>
spin:<FontAwesomeIcon icon={faTwitter} size="4x" spin />
</div>
<div>
shake:<FontAwesomeIcon icon={faTwitter} size="4x" color={"red"} shake />
</div>
<div>
fade:<FontAwesomeIcon icon={faTwitter} size="4x" color={"blue"} fade />
</div>
<div>
beat:<FontAwesomeIcon icon={faTwitter} size="4x" color={"purple"} beat />
</div>
<div>
bounce:<FontAwesomeIcon icon={faTwitter} size="4x" color={"brown"} bounce />
</div>
</div>
);
}
こんな感じになりました。かわいいですね。私はbounceが好きです。
CSSのanimationのほうが細かい指定ができそうですが、シンプルなら使い方ならこれで十分そうです。
補足:アイコン名の規則
補足というほどではないですが、、、。
従来のCSSで指定する方式の場合、<i class="fa-brands fa-twitter"></i>
のように、「fa-種類 fa-アイコン名」の形で指定していました。FontAwesomeIconコンポーネントを使う場合、「fa-twitter」のようにケバブ・ケースだったのが、「faTwitter」のように基本的にはキャメル・ケースになっています。
CSSのclass名ではハイフンは使えますが、Javascriptの変数名では使えないので、そうなっているだけですが、、、知っているとimport時にアイコンを探すのが少し早いかと思ったので一応書いておきました。
Next.jsで使う場合の注意点
上記の例をNext.jsでそのまま使用すると、アイコンが巨大に表示されてしまいます。はみ出るレベルです。
これは、ドキュメントにも以下のように記載されています。
Since Next.js manages CSS differently than most web projects if you just follow the plain vanilla documentation to integrate react-fontawesome into your project you'll see huge icons because they are missing the accompanying CSS that makes them behave.
Next.jsでそのまま使うと、本来適用されるCSSが欠けてしまうのが原因のようです。公式案内のとおり、以下の3行を追加すれば解決できます。
import { config } from '@fortawesome/fontawesome-svg-core'
import '@fortawesome/fontawesome-svg-core/styles.css'
config.autoAddCss = false
なので、Twitterのアイコンを表示させる例だと、こんな感じになります。コンポーネント単位で設定するか、__app.js等で指定して全ページに適用させるかは、用途次第かと思います。
// React用のコンポをimport
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
// 利用するアイコンをimport。
// Twitterのような企業ロゴはbrandsにあります。
import { faTwitter } from "@fortawesome/free-brands-svg-icons"
// 以下3行はNext.js対策
import { config } from '@fortawesome/fontawesome-svg-core'
import '@fortawesome/fontawesome-svg-core/styles.css'
config.autoAddCss = false
export default function TwitterIcon() {
// FontAwesomeIconのiconプロパティに
// importしたアイコンを指定すればOK
return (
<FontAwesomeIcon icon={faTwitter} />
);
}
参考
- Set up with React: https://fontawesome.com/v6/docs/web/use-with/react/
- Adding Icon Styling with React: https://fontawesome.com/v6/docs/web/use-with/react/style
最後に
公式パッケージであるFontAwesomeIconを使って、font-awesome(6.4)を扱う方法について記載しました。
使用するアイコンのみimportでき、使ってないアイコンのCSSがダウンロードされないことに、個人的には一番メリットを感じます。他にも、SVGとなること自体にメリットを感じる方も多いかと思います。
少し経ったら再度Google Search Consoleでテストして、パフォーマンスの評価が改善しているか確認してみたいと思います。
なお、今回は使用するアイコンを個別にimportする方法を紹介しましたが、事前に使うiconのみ定義して使う方法や、プロジェクト内で使うアイコンを一括してimportする、global importと呼ばれている方法もあるようです。慣れてきたら、こちらも試してみようと思います。