Qiitaで使っているアイコンをFont AwesomeからMaterial Symbolsに変えた話。

## はじめに
[Qiita株式会社 Advent Calendar 2022](https://qiita.com/advent-calendar/2022/qiita-inc)の3日目は、
Qiita 株式会社 プロダクト開発G デザインTMの出口（@degudegu2510）が担当します！

普段の業務は、Qiita, Qiita Team, Qiita Jobsでデザイナーとして、情報設計、体験設計(UX)、UIデザイン、フロントエンドまで携わっています。

現在Qiitaでは、アイコンフォントを[Font Awesome](https://fontawesome.com/)から[Material Symbols](https://fonts.google.com/icons)へと順次移行しています。
移行を進めていく中で、大変だったことやそこから得た知見が多くありました。

そのためこの記事では、アイコンフォントをFont AwesomeからMaterial Symbolsへと移行していく中で、
変更した理由や大変だったこと、そこから得た知見等をまとめようと思います。

## アイコンフォント
![image1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390720/1be31b4b-0f71-a837-268d-98ff2807ed85.png)
まずは事前知識として、アイコンフォント、Font Awesome、Material Symbolsについて説明します。

### アイコンフォントとは？
アイコンフォントとは、HTMLのタグや特有のクラス名を付与することで、
Web上にアイコンを簡単に表示できるライブラリ・フォントになります。

書き方は、各アイコンフォントでそれぞれ違いますが、
CSSで大きさや色などを自由に変えられるため、サイトのトンマナに合わせたアイコンを使うことができます。

また、PNGやJPEGなどの画像をアイコンとして表示させるより、書き出し直したりする手間やファイルサイズ等も小さくなるため、表示速度への影響を気にせずに使用することができます。

アイコンフォントといえば、以下のようなものが有名かなと思います。

- **Font Awesome**
    - https://fontawesome.com/
- **Line Awesome**
    - https://icons8.com/line-awesome/howto
- **Material Symbols**
    - https://fonts.google.com/icons
- **Phosphor Icons**
    - https://phosphoricons.com/
- **Remix icon**
    - https://remixicon.com/

### Font Awesomeとは？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390720/66732bfd-bfb0-7a13-f1a4-c7601647eb6f.png)
Font Awesomeは、無料で利用可能なWebアイコンフォントで、約2,000個のアイコンを使うことができ、有料版では、約20,000個程のアイコンが使えるようになります。

また、アイコンをアニメーションさせるためのプロパティが6種類ほどあったり、X(Twitter)やFacebookアイコンといったブランドアイコンが450以上あり充実してます。

https://fontawesome.com/

　
**【基本的な使い方】**
基本的な使い方は、HTMLタグのclassに特定のスタイルを当てることによって、 `::before`としてアイコンが表示されます。

```sample.html
<!-- home アイコンを表示させる時 -->
<span class="fa-solid fa-house"></span>
```

　
### Material Symbols とは？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390720/e0b60e5e-554a-802b-fa43-8aa76b761583.png)

Material Symbolsは、Googleが公式に提供している最新のアイコンフォントで、2,500種類の以上のアイコンを１つのフォントファイルに統合しています。

また、Material Symbolsは、バリアブルアイコンフォントであるため、変更できるのが色やサイズだけでなく、
塗りつぶしや線の太さ・光学的な調整・サイズに適したアイコンの形なども変更することが可能です。

https://fonts.google.com/icons

**【基本的な使い方】**
基本的な使い方は、HTMLタグのclassに特定のスタイル当てて、アイコンの種類を要素として記載するとテキストがアイコンとして表示されます。

```sample.html
<!-- home アイコンを表示させる時 -->
<span class="material-symbols-outlined">home</span>
```

詳しくは、こちらの記事をごらんください。

https://qiita.com/degudegu2510/items/aafc360734b8a423cb00

　
## どうして変えることにしたの？
### Font Awesomeをやめた理由
まず、QiitaがFont Awesomeをやめた理由は3つあります。
　
#### ① アイコンの形が丸く、Qiitaのトンマナと合っていなかった
Font Awesomeをやめた理由の1つ目は、Qiitaのトンマナと合っていなかったからです。
Font Awesomeは、全体的に丸くできており、可愛く感じるアイコンになります。

Qiitaとしては、論理的、合理的、公平な、効率的をイメージできる　幾何学なアイコンが合っていると感じていました。

|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390720/61231e40-8dbd-bd9c-8a6e-e577804b25df.png" width="100%"/>|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390720/e3578b86-a7a7-bfe0-f3d3-c67bf60b8b84.png" width="100%"/>
|:--:|:--:|
|Font Awesome|Material Symbols|


具体的には、↑このように同じhomeのアイコンでも、Font Awesomeは、煙突があったり、屋根が付いており、
Material Symbolsと比べると、可愛く感じます。
また、アイコンの頂点部分も、Font Awesomeは角丸になってる部分が多いのも可愛く感じるのだと思います。

そのため、Font Awesomeは、Qiitaのトンマナと合っていないと感じていました。


#### ② 無料版での種類に限界を感じた。
Font Awesomeをやめた理由の2つ目は、無料版で使えるアイコンの種類に限界を感じたからです。

Qiitaは、ここ数年でいろいろな機能を開発していく中で、使いたいアイコンが見つからないかったり、
見つかっても、有料版のアイコンだったりし、アイコン１つ見つけるのも一苦労でした。

そのため、無料でいろいろなアイコンがすぐ見つかるようなアイコンフォントにしたいと思いました。


#### ③ バージョンアップができていなかった
Font Awesomeをやめた理由の3つ目は、バージョンアップができていなかったからです。

Font Awesomeは、`version 6.2.1` が最新となっていました。
しかし当時のQiitaが使っていたFont Awesomeのversionは、`version 4.7.0`で長期間アップーデートができていませんでした。

アップデートできていなかった理由は、`version 4` から `version 5`・`version 6` で破壊的な変更が行われていたのが原因の1つです。

|![スクリーンショット 2022-12-01 0.02.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390720/93829e71-d056-f4cc-1b32-735c02fa75d2.png)|![スクリーンショット 2022-12-01 0.03.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390720/e14ef32f-cee3-9e7b-65e2-cc1a37052075.png)|
|:--:|:--:|
|`class="fa fa-commenting"`| `class="fas fa-comment-dots"`|

具体的には、 ↑こんな感じに同じアイコンなのにclassが変わるアイコンが多く、
対応しないといけないアイコンも多かったため、対応コストと成果という面から後回しになり気づいたら、`version 6`がリリースされていたというわけです。

そのような状況の中で、`version 4`がサポート対象外になったことで、アイコンフォントを変えることを決断しました。


### Material Symbolsに変えることにした理由
アイコンフォントを変えるにあたり、重視したポイントは以下の3点です。

+ Qiitaのトンマナに合っていること
+ アイコンの種類が多いこと
+ アップデートで破壊的な変更が少ないこと

その観点から、2、3個のアイコンフォントに絞りました。

その2、3個のアイコンフォントの中で、ポイントになったのは、
Material Symbolsがバリアブルアイコンフォントであったことです。

特に、Material Symbolsは、light modeやdark modeで同じ見た目にするための光学的な調整ができたり、
アイコンのサイズに合わせた形になっていたりという点に使いやすさを感じました。

また、Figma上にMaterial Symbolsを呼び出せるプラグインがあったことも大きいです。

このようなことから、Material Symbolsに変えることに決めました。

## 大変だったこと
### ① レイアウトシフトが発生したこと
大変だったことの1つ目は、Material Symbolsをはじめに使ってみた時にレイアウトが発生してしまったことです。

Material Symbolsがアイコンを表示するまで順番としては以下のようになっています。

`DOMを表示 → stylesheet・フォントを読み込み → アイコンに反映させる`

インターネット環境によっては、DOMを表示されてから、アイコンに表示されるまでラグがあり、
その間、代替フォントでテキストが表示されてしまい、レイアウトシフトが発生してしまいました。

`font-display` によって、フォントがダウンロード済みで利用できるかに基づいて表示をコントロールできます。
しかし、ダウンロードされてから、反映するタイミングでも、代替フォントで表示されてしまうため、レイアウトシフトを止めることができませんでした。

そこでQiitaでは、レイアウトシフトを止めるために、
フォントサイズに応じて、widthやheightを固定値にして、`overflow: hidden`で代替フォントで表示されたテキストを部分的に隠すというものです。

イメージは↓こんな感じです。

```sample.css
.icon {
  font-size: 24px;
  height: 24px;
  overflow: hedden;
  whidth: 24px
}
```

### ② 変更ファイル数が多いこと
大変だったことの2つ目は、変更が必要なファイルが多いことです。

Material Symbolsに変えることを決めた時から、
Font Awesomeがどこで、どんな形で呼び出されているかまでは、把握できていなかったので
ある程度多いのは覚悟していました。

そんな中で、完全にFont Awesomeを消し去るまでやらないと負債として残ってしまうので、ちゃんと全てのページを網羅できるように
することを意識して、計画・スケジュールを決めました。

いくつか変更していくための方法が上がった中で、
変更する人・プルリクをレビューする人どちらにとっても、負担が少なくなり、
変更箇所が分かりやすく、網羅しやす方法として、routeを上からn行目からm行目までのように進めていくことに決めました。

複数のURLで同じコンポーネントを使っていることもおおく、コンフリクトする可能性がある方法ですが、抜け漏れが発生し、アイコンが表示されないということがないようにすることを重視していたため、マージが遅れた人がコンフリクトを修正するようにしています。

*※ できるだけコンフリクトを避けるために、マージされるまで、次のissueには着手しないようにはしています。*

### ③ Material Symbolsの使い方を説明すること
大変だったことの3つ目は、メンバーにMaterial Symbolsの使い方を説明することです。

Qiitaでは、Qiita Teamを社内ドキュメントとして、使っているため、Material Symbolsの使い方の記事を書き、MTG等で説明ました。
しかし、実際に触ってみないと理解が深まらないという部分もあるため、都度、口頭で使い方を聞かれたりする傾向もあったため、誰でも迷わず使えるように、Material Symbolsを表示させるコンポーネントを作成しました。

イメージは、↓こんな感じです。

```MaterialSymbols.tsx
import { css } from '@emotion/core'
import React, { ReactNode } from 'react'

interface Props {
  children: ReactNode
  type?: 'outline' | 'rounded' | 'sharp'
  fill?: boolean
  weight?: 100 | 200 | 300 | 400 | 500 | 600 | 700
  grade?: -25 | 0 | 200
  opticalSize?: 20 | 24 | 40 | 48
}

export const MaterialSymbol = ({
  children,
  type = 'outline',
  fill = false,
  weight = 400,
  grade = 0,
  opticalSize = 24,
}: Props) => {
  return (
    <span
      css={symbolStyle(fill, weight, grade, opticalSize)}
      className={`material-symbols-${type}`}
    >
      {children}
    </span>
  )
}

const symbolStyle = (fill: boolean, weight: number, grade: number, opticalSize: number) =>
  css({
    display: 'inline-block',
    flexShrink: 0,
    fontVariationSettings:
      `'FILL' ${fill ? 1 : 0},
      'wght' ${weight},
      'GRAD' ${grade},
      'opsz' ${opticalSize}`,
    height: opticalSize,
    overflow: 'hidden',
    width: opticalSize,
  })
```



## まとめ
そのためこの記事では、アイコンフォントをFont AwesomeからMaterial Symbolsへと移行していく中で、
変更した理由や大変だったこと、そこから得た知見等をまとめました。


変更範囲も大きく、アイコンの種類や書き方も複数あるため、一括でgrepして、どかっと変更すると、剥け漏れが発生するので、
慎重に1ページずつ対応しています。

現在は半分以上は対応済みのため、Qiitaで使われているアイコンの半分以上は、Material Symbolsになりました。
残りの部分もちょくちょく対応しながら、Font Awesomeをなくしていこうと思います。


[Qiita株式会社 Advent Calendar 2022](https://qiita.com/advent-calendar/2022/qiita-inc)の4日目は、
@mziyutが担当します！

ぜひ[Qiita株式会社 Advent Calendar 2022](https://qiita.com/advent-calendar/2022/qiita-inc)を購読して、明日以降の記事もご覧いただけると嬉しいです。

---

最後まで読んでくださってありがとうございます！

普段はデザインやフロントエンドを中心にQiitaに記事を投稿しているので、ぜひQiitaのフォローとX(Twitter)のフォローをお願いします。

https://twitter.com/degudegu2510