font-sizeの指定をする場合、単位の選択肢としては、px(ピクセル)、em(エム)、rem(レム)の三つが挙げられます。
どれが正しく、どれが間違いという訳ではありませんが、ベストプラクティスは「rem」です!
ただ、一般に多く出回っているのは「px」です。駆け出しのコーダーから、制作会社のベテランまでpxを使う方は非常に多くいます。
そこで今回はなぜ「rem」がいいのかということと、remの正しい使い方を解説します。
合わせてcss変数やcalc関数を使った記述の仕方や、clamp関数を使ったレスポンシブ対応の書き方まで解説しています。
パフォーマンスやアクセシビリティの向上を考えてコードを書く方は必見です。ぜひ参考にしてください。
px,em,remの違い
px、em、remのどれを使うかは、用途や目的によって異なります。それぞれにメリットとデメリットがあるため、状況に応じた適切な選択が重要です。
1. px (ピクセル)
固定サイズの単位で、絶対的な単位です。
メリット
- 一貫したサイズを保持できるため、デザイン通りに表示されやすい。
- 小さなデザインパーツやアイコンなど、正確なサイズが求められる場合に適している。
デメリット
- レスポンシブデザインにおいて、デバイスの画面サイズやユーザーのアクセシビリティ設定に対応しにくい。
- ユーザーがブラウザで文字サイズを変更しても反映されない場合がある。
2. em(エム)
親要素のフォントサイズに基づく相対単位です。
たとえば、親要素のフォントサイズが16pxの場合、1emは16pxに相当します。もし子要素で2emと指定すれば、その要素のフォントサイズは32pxになります。
メリット
- 親要素に依存してサイズが決まるため、レスポンシブで柔軟に対応できる。
- 子要素のサイズを調整しやすい。
デメリット
- ネストされた(入れ子になった)要素で使うと、意図しないサイズの拡大や縮小が発生することがあり、管理が難しくなる。
3. rem(レム)
ルート(html)要素のフォントサイズに基づく相対単位です。
たとえば、ブラウザのデフォルト設定ではhtml要素のフォントサイズは16pxです。もしhtml要素に特別なフォントサイズ指定がなければ、1rem = 16pxとなります。
メリット
- emの柔軟性を持ちながら、ネストの影響を受けないため、サイズ管理が簡単。
- 全体のフォントサイズを1箇所(html要素)で調整できるため、一貫性のあるデザインが可能。
- レスポンシブデザインやアクセシビリティの向上にも役立つ。
デメリット
- remのサイズは、ルート要素に依存しているため、初めて使う際には理解に時間がかかる場合がある。(後ほどこのデメリットを解決する方法を解説します)
px,em,remのまとめ
pxのデメリットはユーザーがブラウザで文字サイズを変更した場合に、反映されない場合があるということです。
反映される場合もありますが、アクセシビリティの面で信頼性が低くなるため、一貫性を保ちたい場合やアクセシビリティを重視したい場合には、emやremを使用した方がいいでしょう。
ただし、emの場合は親が変わると、サイズが変わる可能性があるといった分かりにくさの問題から、remがベストプラクティスになるというわけです。
bodyにfont-size:62.5%;を設定するのは非推奨
bodyに対して font-size: 62.5% を設定する方法は、かつて一般的に使われていたテクニックですが、現在では問題が起きる可能性があるので非推奨となっています。
その問題とは、62.5%に設定すると、ユーザーが設定したフォントサイズが適切に反映されないことがあるということです。つまり、px指定と同様の問題を引き起こす可能性があるのです。
また、一部のブラウザや環境、特に古いブラウザや一部のモバイルブラウザでは、フォントサイズをパーセンテージで指定すると、予期しない動作が発生するといった問題もあります。
では、なぜ62.5%が使用されていたかというと、それは、制作者にとって分かりやすいからという理由です。
通常、ブラウザのデフォルトのフォントサイズは16pxです。そこでbodyに62.5%にすると16pxの 62.5% で10px になるため、remでフォントサイズを指定するときに、1rem = 10px として計算しやすくなります。
たとえば、font-size: 1.6rem; とすると、16pxになり、px単位で考えるのが直感的になるという理由から、この手法が使われていました。
制作者側にとってメリットがあっても、ユーザー側にはデメリットになる可能性があるので、この手法は非推奨です。
css変数(カスタムプロパティ)とcalc関数の利用
ただ、remで書くと分かりにくいといったデメリットがあります。
デザインカンプ通りに正確に作りたい場合などにも不便です。
そこでおすすめするのがcss変数とcalc関数を使う方法です。
以下の例では、:rootで24pxをremに置き換え、.fz24の箇所で呼び出しています。
:root {
--24: calc(24 / 16 * 1rem);
}
.fz24 {
font-size: var(--24);
}
これで、fz24のクラス名の箇所はfont-size: 24px;をremに直したもの(1.5rem)で表示できます。
通常、使用するフォントサイズはいくつもあるので、以下のようになります。
:root {
--14: calc(14 / 16 * 1rem);
--16: 1rem;
--24: calc(24 / 16 * 1rem);
--32: calc(32 / 16 * 1rem);
}
body {
fonts-size: var(--16);
}
.title {
font-size: var(--32);
}
.subTitle {
font-size: var(--24);
}
.smallText {
font-size: var(--14);
}
後からcssを見たときも、これだと分かりやすいですね。
ただし、変数の設定を忘れていると、反映されないのでお気をつけください。
フォントサイズをClamp関数を使ってレスポンシブ対応させる方法
フォントサイズはスマホとパソコンで大きさを変える場合がほとんどですが、一般的には以下のようにメディアクエリを使った方法が採用されています。
:root {
--32: calc(32 / 16 * 1rem);
--56: calc(56 / 16 * 1rem);
}
.title {
font-size: var(--32);
@media (min-width: 1200px) {
font-size: var(--56);
}
}
今回はclamp関数を使って、よりシンプルに、よりパフォーマンスやアクセシビリティを向上させる方法を紹介します。
VSCode拡張機能「Clamp it!」
VSCode(VisualStudioCode)エディターを使っている方はこの拡張機能がかなりおすすめです!
まずは「Clamp it!」を検索し、インストールしてください。
インストールが終わったら、左下の歯車マークからSettingを選択し、「clamp」を検索します。
ここでデフォルトのベースフォントやビューポートの設定を変更することができます。
ベースフォントは16pxが一般的なので、このままでOKです。ビューポートはMaxとMinがあります。
実装してみてからの方が分かりやすいかもしれませんが、簡単に説明すると、Minがフォントサイズが変わり始める画面幅で、Maxがフォントサイズが変わり終わる画面幅です。
あとでも変更できるので、とりあえずこのままで進みます。
では、VSCodeでcssファイルを開き、以下のように記述します。
:root {
--32_56: 32px, 56px
}
次は32px, 56pxを選択したまま、macの場合は「shift」+「command」+「p」を、Windowsの場合は「shift」+「control」+「p」を押します。
出てきたボックスに「clamp it」と入力します。
「Enter」を押すと、clamp関数で書き換えられた値が出ます。
このclamp関数は、スマホサイズでは32pxですが、画面幅が600px以上になると、徐々に大きくなり始め、画面幅が1200pxになると56pxになり、それ以上大きくはならないという設定になります。
:root {
--32_56: clamp(2rem, calc(0.5rem + 4vw), 3.5rem);
}
.title {
font-size: var(--32_56);
}
このコードをブラウザに表示すると以下の動画のようになります。
見ていただくとわかるように、画面幅が600pxから1200pxの間にフォントサイズが変わっています。
clamp関数とメディアクエリの比較
では、今書いたclamp関数のコードの下に、先ほどのメディアクエリのコードを書いて比較してみましょう。
:root {
--32_56: clamp(2rem, calc(0.5rem + 4vw), 3.5rem);
--32: calc(32 / 16 * 1rem);
--56: calc(56 / 16 * 1rem);
}
.title {
font-size: var(--32_56);
}
.titleMedia {
font-size: var(--32);
@media (min-width: 1200px) {
font-size: var(--56);
}
}
これをブラウザに表示させると以下の動画のようになります。
上のclamp関数を使った方は滑らかに文字の大きさが変わっていきますが、下のメディアクエリを使った方は1200pxで急に変わっています。
ユーザーが様々なデバイスで画面を見ることを想定すると、明らかにclamp関数の方がいいですよね。
また、コードの記述量もclamp関数は一行で書けますが、メディアクエリだと三行になります。(メディアクエリを増やせばさらに記述は増えます。)しかも、フォントサイズの設定は複数箇所でするため、その分コードの量は増えます。
コードが増えればパフォーマンスに影響が出るだけでなく、保守などで後からコードを見た時にも分かりにくく、複雑になるほど時間がかかってしまいます。
アクセシビリティ、パフォーマンス、保守の面などの様々な観点から、clamp関数の方がいいのは明らかです。
コード上でのデフォルト値の変更の仕方
では、合わせてデフォルトのベースフォントとビューポートの変更の仕方も解説しておきます。
今は初期設定が、ベースフォントが16px、ビューポートmaxが1200px、ビューポートminが600pxになっています。
先ほどの説明した通り、VSCodeの設定で変更することもできますが、コード上でも変更できます。
たとえば、画面幅が480pxから1024pxの間でフォントサイズ14pxから18pxに変えたいときは、以下のように記述します。ベースフォントは16pxのままです。
:root {
--14_18: 14px, 18px, 16px, 480px, 1024px
}
最小フォントサイズ、最大フォントサイズ、ベースフォントサイズ、最小ビューポート、最大ビューポートの順で記述し、あとはこれら全てを選択し、先ほどと同じようにMacの場合は、「shift」+「command」+「p」を押し、「Clamp it」を選択して「Enter」を押せばコードが生成されます。
:root {
--14_18: clamp(0.875rem, calc(0.654rem + 0.735vw), 1.125rem)
}
ただし、ビューポートを変えると、後から見た時に分からなくなるので、以下のようにコメントを書いたり、変数名を変えたりすることをおすすめします。
:root {
--32: calc(32 / 16 * 1rem);
--56: calc(56 / 16 * 1rem);
/* vp600px~1200px */
--32_56: clamp(2rem, calc(0.5rem + 4vw), 3.5rem);
/* vp480px~1024px (tablet用)*/
--t14_18: clamp(0.875rem, calc(0.654rem + 0.735vw), 1.125rem)
}
VSCodeを使っていない場合
VSCodeを使っていない場合は、以下のサイトでclamp関数のコードが生成できます。
https://min-max-calculator.9elements.com
https://wearerequired.github.io/fluidity
コードを生成し、コピペする必要がありますが、同じことができます。
私も拡張機能「Clamp it!」を知るまでは、上記のサイトを利用させてもらっていました。
まとめ
今回はフォントサイズは「rem」がベストプラクティスということと、css変数やcalc関数を使った記述の仕方、clamp関数を使ったレスポンシブ対応の書き方まで解説しました。
今後も当ブログでは、パフォーマンスやアクセシビリティの向上に関する記事を書いていきますので、ぜひ楽しみにしていてください。
フロントエンドに関する記事では、以前、OGPやfaviconに関する記事を書いています。
よろしければこちらも合わせてご覧ください。