Material Symbolsの現実的な導入方法

## この記事の概要

2022年4月頃、Material Design IconsがMaterial Symbolsにアップデートされたのは記憶に新しいです。
軽く使ってみたところ、性能を活かしつつパフォーマンスに悪影響を与えないためには、公式の説明の行間を読まねばなりませんでした。

というわけで、試した内容を記事にしました。

なお、Material Symbols自体の説明はこちらの記事で行っています。

https://qiita.com/xrxoxcxox/items/c7946d6b50589087f802

## 使い方の前に、Material Symbolsの特徴

https://fonts.google.com/icons

- Outlined, Rounded, Sharpの3 styles
- 100から700までの7 weights
- オンオフできるfill
- -25, 0, 200の3 grades（強調度合いの変更や、ダークモード用の視覚調整）
- 20, 24, 40, 48の4optical sizes（自然な線幅の印象になるような調整）

これらの特徴を上手く使い分けることで、表示される大きさや周辺の要素にフィットするようなアイコングラフィーを実現できるようになります。

## 公式に書いてある導入方法 1

`Variable icon font`という名前で記載されている方法です。
先ほど紹介したパラメータをコード内でいくらでも変更できるやり方です。

例えば、`Outlined`styleのアイコンを導入したいとして、以下のコードをHTMLに挿入すればほとんど終わりです。[^font-variation-settings]

[^font-variation-settings]: CSSに`font-variation-settings`の設定をすることで柔軟にスタイルを出し分けられるようになりますが、ここでは省略します。

```html
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
```

ただ、非常に重くなります。
以下の画像にある`kJEhBvY...`という名前のフォントファイルがMaterial Symbolsのデータなのですが、2.0 MB。
さすがに嫌ですね。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/340361c7-204e-dc04-1f5f-5141b29624b1.png)

## 公式に書いてある導入方法 2

`Static icon font`という名前で記述されている方法です。
あらかじめ設定した1つの設定だけをロードします。

以下のスタイルを導入したいとします。

- Outlined
- Fill: あり
- Weight: 400
- Grade: 0
- Optical size: 24

この場合、次のコードをHTMLに挿入すれば終わりです。[^no-font-variation-settings]

[^no-font-variation-settings]: `Variable icon font`のときと違い、設定を変えられる箇所が無いのでCSS側での`font-variation-settings`設定は必要ありません。

```html
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,1,0" />
```

こちらの方法であれば、かなり軽く済んでいます。（225 kB）
ただ、せっかく色々なパラメータがいじれるのが特徴のMaterial Symbolsでこの方法だと、若干活かしきれていないように感じてしまいます。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/4f52c14e-a225-0302-81f1-ae9e70dab64f.png)

## 行間を読んだ導入方法

例えば、以下のスタイルを導入したいとします。

- Outlined
- Fill: 両方使いたい
- Weight: 400
- Grade: -25, 0（ダークモード対応を視野に入れている）
- Optical size: 24

この場合、先ほどのリンクを以下のように変更します

```diff
- <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,1,0" />
+ <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0..1,-25..0" />
```

URLの最後の`opsz,wght,FILL,GRAD@XXX,XXX,XXX,XXX`という箇所に各種パラメータを埋め込んでいるのですが、`..`で繋ぐことで範囲指定されています。
実は`Variable icon font`で紹介したURLも単に`opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200`とすべてのパターンを呼び出しているに過ぎませんでした。

このように、必要な部分は複数パターン読み込んでおいて、固定して構わないパラメータは固定しておくと、パフォーマンスと種類の豊富さを両立しやすいと思います。

`Static icon font`のときほどではありませんが、すべて読み込んだ2.0 MBと比べればだいぶ軽くなっています。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/8a7018bf-805e-8ab2-aaa7-b1f730c437e2.png)

## 余談：ダメだった方法

以下のように複数種類呼び出しても、最後に呼び出した設定が勝ってしまい、他の3つの設定は使えませんでした。
よく考えれば当たり前なのですが、少し戸惑ったので一応記載しておきます。

```html
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,1,0" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,-25" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,1,-25" />
```

---

最後まで読んでくださってありがとうございます！
Twitterでも情報を発信しているので、良かったらフォローお願いします！

https://twitter.com/xrxoxcxox