【CSS】font-sizeには「px」ではなく「rem」を使うべき

この記事では、ウェブアクセシビリティの観点において、ベストプラクティスとなり得る`rem`単位を使うべき理由ついて説明します。

## 結論
:::note
- font-sizeの指定には絶対単位（ `px` ）は使用せずに相対単位（`rem`）を利用する ＜適合レベル AA＞
:::

ウェブコンテンツの文字サイズに絶対単位を指定すると、ユーザーがブラウザの設定でフォントサイズを変更することが出来なくなります。
これではウェブアクセシビリティの国内規格の適合レベルAAの達成基準を満たすことができないため、適合要件を満たす相対単位での指定が推奨されます。

## 前提知識

### ウェブアクセシビリティとは
ウェブアクセシビリティとは、すべてのユーザーがウェブコンテンツに等しくアクセスできるようにすることを意味します。
国内規格である「[JIS X 8341-3:2016](https://waic.jp/docs/jis2016/understanding/201604/)」は、国際基準「[WCAG 2.0](https://waic.jp/translations/WCAG20/Overview.html)」に基づいており、視覚や聴覚に障害がある人や高齢者などがウェブサイトを利用しやすくするガイドラインを定めています。この規格の遵守により、社会的包摂性が高まり、法的義務の履行、SEOやブランド価値の向上が期待されます。

最近では、障害者差別解消法により、障害のある人々に対して合理的配慮を行うことが事業者や公共機関に義務付けられました。

https://waic.jp/docs/jis2016/understanding/201604/


### ウェブアクセシビリティのよくある誤解
> 文字を大きくしてサイトを閲覧する必要があるユーザーや、色を変更してサイトを閲覧するユーザーは、特定のサイトだけではなくすべてのサイトで同じ状態になっていることを望みます。そのため、ユーザーが使っているパソコンやスマートフォンなど、デバイス（その OS）が提供している設定項目を調整してカスタマイズしていることが多く、特定のサイトに付加された機能を積極的に使いたいわけではないのです。

出典：ウェブアクセシビリティ導入ガイドブック

https://www.digital.go.jp/resources/introduction-to-web-accessibility-guidebook

:::note
文字サイズ拡大ボタンのようなユーザー補助のための機能を設置すれば、アクセシビリティが向上できるわけではない
:::

このことから、デバイスやブラウザが提供している設定項目を調整してカスタマイズする状況に対応できる記述を心がけるべきでしょう。

## 達成基準
### ■ 達成基準 1.4.4 テキストのサイズ変更 ＜レベル AA＞

https://waic.jp/translations/WCAG22/#resize-text

> キャプション及び文字画像を除き、テキストは、コンテンツ又は機能を損なうことなく、支援技術なしで 200％ までサイズ変更できる。

この項目では、文字サイズがサイズ変更できるか、サイズ変更を行った際の閲覧及び操作が問題ないか、を判定します。
後者の判定は前者のサイズ変更が可能であることを前提とするため、本記事ではサイズ変更の可否について値の指定方法を確認していきます。

### ― ■ 文字サイズの変更
文字サイズの変更には、ブラウザが提供している設定項目にて実現できます。
Google Chrome を利用している場合、下記の操作で変更することができます。

- [設定 (chrome://settings/)] > [デザイン] > [フォントサイズ]

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3829416/4f6acb59-4a55-914f-f5f6-720a4d58fe91.png)

ブラウザの設定からフォントサイズを変更することができる状態で、次のフォントサイズの単位ごとの挙動を確認できるサンプルコードの表示を確認してください。

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="poXbdMr" data-pen-title="フォントサイズ単位の検証" data-user="yukimura1228" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/yukimura1228/pen/poXbdMr">
  フォントサイズ単位の検証</a> by 岡田 幸樹 (<a href="https://codepen.io/yukimura1228">@yukimura1228</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

フォントサイズの設定を変更することで、`rem`単位の文字サイズのみ変更されることが確認できると思います。これは、`rem`単位がルート要素のテキストサイズ（デフォルト値：`font-size: medium;`）を参照していることで可変されるためです。
`em`, `%`単位の指定も同じく相対単位ではありますが、参照する親要素が絶対単位で指定されている場合、フォントサイズの設定を反映することはできません。

ブラウザの設定でフォントサイズが変更可能な単位は以下の通りです。

- `px`：変更できない
- `em`：変更できる（親要素が絶対単位の場合は不可）
- `rem`：変更できる（ルート要素が絶対単位の場合は不可）
- `%`：変更できる（親要素が絶対単位の場合は不可）
- `vw`：変更できない
- `vh`：変更できない


もちろん文字サイズ変更ボタンのようなユーザー補助機能を用意すれば、絶対値を書き換えることも可能ですが、それすらもあらかじめ相対値で指定しておいて相対基準値を操作する方が容易に実現出来るでしょう。

## 推奨される対応
ブラウザの文字サイズの変更に対応するためには、`font-size`プロパティに相対単位を指定する必要があることを確認しました。
相対単位の中でも`rem`は、ルート要素のフォントサイズに一意に基づくため、より簡潔にフォントサイズを指定することができます。

### ■ ルート要素（`<html>`タグ）への指定
:::note
【推奨】
- ルート要素（`<html>`タグ）のfont-sizeの指定には、
デフォルト値の `medium` / `100%` を利用する
:::

:::note alert
【非推奨】
- ルート要素（`<html>`タグ）のfont-sizeの指定に、
絶対単位（`px`）を利用している
- 「10px = 1rem」として利用しやすいように `font-size: 62.5%`を指定している
:::

`rem`単位で参照されるルート要素（`<html>`タグ）には
- 基準値として絶対単位の指定されている（`font-size: 16px;`）、
- 開発者が利用しやすいように基準値が書き換えられている（`font-size: 62.5%;`）

ようなケースがあります。そのような場合、正しく文字サイズの変更が正しく反映されないため、ルート要素への`font-size`の指定も確認するようにしましょう。
第三者のコードによって書き換えられてしまっている場合には影響範囲を確認して判断するようにしてください。

### ■ テキスト要素（`<p>`タグ等）への指定

:::note
【推奨】
- テキスト要素（`<p>`タグ等）のfont-sizeの指定には、
相対値の `rem` を利用する
:::

:::note alert
【非推奨】
- テキスト要素（`<p>`タグ等）のfont-sizeの指定に、
絶対単位（`px`）を利用している
:::


## まとめ
ウェブアクセシビリティの達成基準を考慮したページ制作を行う場合、フォントサイズにはサイズ変更が可能な相対単位（`rem`）を指定しましょう。
また、基準値の指定にはデフォルトの値（`font-size: medium;`）を参照しておくことで常に標準化されている値をベースにすることが出来ます。

## 終わりに
フォントサイズには様々な単位指定がありますが、ウェブアクセシビリティに基づく観点からベストプラクティスとして相対値（'rem'）が定着されることを望んでいます。

しかしながら、デザインデータは`px`単位なので、直観的に`rem`単位を利用しづらいという問題があります。様々なハックがありますが、`16px = 1rem`のデフォルト基準で指定するか、CSS変数にあらかじめ`rem`単位の`px`対応を定義しておいて利用する方法を推奨します。

質問やフィードバックがありましたら、ぜひコメントでお知らせください。