Webサイトのfont-size・・・それでも僕は相対値。

こんにちは。
どうもしばひろです。
皆さんは、Webサイトをコーディングする時、文字サイズはどうやって指定してますか?
「px
」や「pt
」などの絶対値ですか?
それとも「rem
」や「em
」などの文字サイズをベースとした相対値ですか?
CSSには色んな単位があり、色んな考え方があります。
一概にどれがベストだとかは言えませんが、僕は基本「rem」や「em」などの文字サイズをベースとした相対値で文字サイズを指定しています。
最近では、「もう、rem
やem
などの文字サイズをベースとした相対値じゃなくてpx
でいいんだよ。」系のツイートやブログを目にすることが多いのですが、それでも僕は今現在は、rem
や em
などの文字サイズをベースとした相対値を使っています。
あ、決して 「px
で font-size
を指定しているサイトはダメだ!」とか、「今日から君も rem
を使うんだ!」とか言うつもりは全くありません。
あくまで、px
でfont-size
を指定してるサイトが多い中、なぜ僕は rem
やem
を使っているのかということを書いてるだけの記事になります。
この記事では「Webアクセシビリティ Advent Calendar 2020」の17日目の役割を兼ねて、なぜ僕が文字サイズベースの相対値を使ってるかについてを書いてみたいと思います。
本当は、この記事のドラフト版が出来てサロンメンバーにお披露目していたちょうどその日に、Twitterでこの font-size
に関するツイートをタイムラインでたくさん見かけて、それから数日後、色んな有識者の方がこの記事と同じような内容のツイートや記事を書かれていたので、もうこの記事をお蔵入りにしようと思ってたんです。
ま、でも一応ここまで書いたし公開することにしました。
そもそもfont-sizeって
font-size
はWebサイトの文字サイズを変更することができるCSSのプロパティです。
値の指定には色んな方法があって、px
やpt
などといった絶対単位や、rem
やem
などの相対単位を使った数値による指定や、親要素の文字サイズに対してのパーセンテージでの指定、文字サイズを表すキーワードで指定することが出来ます。
/* ==============================
数値による指定
============================== */
/* 絶対単位(px, pt, cm, in など) */
p {
font-size: 14px;
}
/* 相対単位(rem, em, ex, vw, など) */
p {
font-size: .875rem;
}
/* ==============================
パーセンテージによる指定
親要素の文字サイズに対しての割合
============================== */
p {
font-size: 87.5%;
}
/* ==============================
キーワードによる指定
============================== */
/* 絶対サイズ( x-small, small, medium, large, x-large など) */
p {
font-size: small;
}
/* 相対サイズ( smaller, larger) */
p {
font-size: smaller;
}
/* ==============================
どのプロパティでも使える値
inherit(親要素を継承), initial(初期値), unset(リセット)
============================== */
p {
font-size: inherit;
}
初期値は「medium
」で、多くのブラウザではブラウザの文字サイズ設定が「中」の時は 16px の大きさになります。
ただ、font-size
は「継承する」プロパティなので、初期値に「medium
」が設定されているのは、ルート要素であるhtml
要素 のみで、その他の要素に関しては、特に文字サイズを指定していない場合、親要素の文字サイズを継承したサイズ、つまり親要素と同じ文字サイズになります。(small
要素などブラウザのCSSで文字サイズを指定されている要素は同じ大きさではありません。)

従って、特に文字サイズを指定していない場合は、html
要素の文字サイズを変更すると、そのページの子要素の文字サイズも変わるってことですね。

文字サイズを変更するのは実装者?それともユーザー?
html
要素の文字サイズを変更すると子要素の文字サイズも変わるって書きましたが、文字サイズを指定するのは誰でしょうか?
基本的にWebサイトを制作している段階であれば、実装者がCSSのfont-size
プロパティを使って文字サイズを指定すると思います。
じゃあ、サイトを公開してからは?
サイトを閲覧している時は、ユーザーが自分好みにサイトの文字サイズを調整したり出来ます。
たまにWebサイトの上部に「大」、「中」、「小」という文字サイズを変更するボタンがついてるサイトもありますが、それを使わずとも多くのブラウザはデフォルトの文字サイズを変えれます。(Safariはなくなりました。)
これはブラウザにあるズーム機能とは別です。
ズーム機能はWebサイト全体を拡大したり縮小したりする機能で、文字サイズだけじゃなく画像やレイアウトも全て大きさが変わります。
ここでいう文字サイズの変更機能は文字サイズのみを変更する機能のことで、例えばGoogle Chromeの場合はアドレスバーの並びの右端に団子ボタンがあるので、そこをクリックして表示されるメニューから「設定」を押します。

その中の「デザイン」という項目に「フォントサイズ」がありここで文字サイズを「大」とか「小」などに変更できるんです。

つまり、文字サイズは実装者側だけじゃなく、ユーザー自身が自分の環境や状況に合わせて文字サイズを変更することもあるんです。
この様に、ブラウザには制作者側ではなくユーザー側でユーザーの自分好みに設定を変えれる機能が色々と備わっています。
「大」とか「小」など決められた大きさだけではなく、「フォントをカスタマイズ」から細かく文字サイズやデフォルトの書体を設定することだって出来ます。
ガイドラインにも書いてある
ユーザーが文字サイズを変更できるように実装することは、WCAG2.1(W3Cが勧告しているアクセシビリティのガイドライン)にもあります。
Except for captions and images of text, text can be resized without assistive technology up to 200 percent without loss of content or functionality.
Web Content Accessibility Guidelines (WCAG) 2.1 – Success Criterion 1.4.4 Resize text
とのことです。
これは、ウェブアクセシビリティ基盤委員会 (WAIC) の翻訳ワーキンググループ さんの和訳を引用させてもらうと
キャプション及び文字画像を除き、テキストは、コンテンツ又は機能を損なうことなく、支援技術なしで 200% までサイズ変更できる。
Web Content Accessibility Guidelines (WCAG) 2.1 – 達成基準 1.4.4 テキストのサイズ変更
と和訳されております。
つまり、「文字サイズは変更できるように実装しておきましょうね。」ということですね。
文字サイズ変更機能の有効と無効
さぁ、では今見てるこのShibajukuのサイトで実際に文字サイズ変更機能を使って文字サイズを変えてみて下さい。
とうですか?変わりましたか?
「大」にすると文字が大きくなり、

「小」にすると文字が小さくなったと思います。

これが文字サイズの変更機能です。
これだとブラウザのズームとは違い、画像やレイアウトまでもが大きくなるわけではないので、レイアウトはそのままで文字だけが大きくなるんです。
これを自分好みの文字サイズに設定しておくことで、自分が一番読みやすい文字の大きさでWebサイトを閲覧できます。
では、今度は色んなWebサイトでこの文字サイズ変更機能を試してみてください。
どうですか?
文字サイズが変わるサイトと、変わらないサイトがあったんじゃないでしょうか?
そうです。実は、font-size
をpx などの絶対単位で指定しているサイトは文字サイズ変更機能では文字サイズが変わりません。
例えば、fonm-size: 12px
と指定したら、ブラウザの文字サイズ変更機能で「大」にしようが、「小」にしようが12pxです。
これが絶対単位です。
反対に rem
や em
で文字サイズを指定してるサイトは、ブラウザの文字サイズ変更機能で文字サイズの変更が可能です。
それはrem
やem
が文字サイズに対する相対単位だからです。
- em
- その要素自身の文字サイズに対する倍率で指定する単位。ただし
font-size
プロパティで使用する場合は、親要素の文字サイズに対する倍率で指定する。 - rem
- ルート要素(基本は
html
要素)の文字サイズに対する倍率で指定する単位。ルート要素のfont-size
で使うとブラウザの既定値に対する倍率で指定する。
例えば rem
はルート要素、つまりhtml
要素の文字サイズに対しての倍率を指定する単位です。
html
要素は、先にも書いた通り特に何も設定していなければ、font-size
は「medium
」になっており、これは、ブラウザの文字サイズ変更機能が「中(デフォルト)」の時は、一般的なブラウザで 16px となります。
なので、基本的にはhtml
要素のデフォルトの文字サイズは16pxと思ってもらって問題ないと思います。
つまり、font-size: .75rem
と指定すると 16px の 0.75倍 ということになり、文字サイズは 12pxになります。
p {
font-size: .75rem; /* 16px × 0.75 = 12px */
}
ブラウザの文字サイズ変更機能は、このhtml
要素の文字サイズを変更する機能だと思って下さい。
Google Chromeの場合は以下の表のようになります。
設定値 | デフォルトの文字サイズ |
---|---|
極小 | 9px |
小 | 12px |
中(デフォルト) | 16px |
大 | 20px |
極大 | 24px |
例えばhtml
要素の文字サイズを「大」変更したら、html
要素の文字サイズが「20px」になり、font-size: .75rem
となっているところは、20px からの0 .75倍の15pxになります。
つまり、html
要素の文字サイズに応じて文字サイズが変更してくれるんです。
p {
font-size: .75rem; /* 20px × 0.75 = 15px */
}
これだったら、ブラウザの文字サイズ変更機能を妨げないのです。
僕はなるべく、こういったユーザーが自分好みに設定できるブラウザが持ってる機能を、有効に活用したいと思ってるタイプです。
とはいえ、全てに対応できてるわけじゃないです。
例えば、iPhoneのGoogle Chromeには「PC版サイトを見る」という機能があります。
スマホ用のデザインではなく、PCサイトのデザインでサイトを表示することが出来る機能です。
でもこれはスマホでのアクセスを疑似的にPCだと思わせてPCサイトのデザインを表示している機能なので、レスポンシブで組んでたら意味ないです。
だってレスポンシブはユーザーエージェントに合わせてHTMLを切り分けているのではなく、画面の幅などでCSSを切り分けてるテクニックだからです。
僕はレスポンシブで作ることが多いので、この機能には対応できてません。
また、「フォントのカスタマイズ」にある、書体の設定も僕はサイトを作る時にCSSで font-family
を設定してしまっているので対応できてません。
でも、なるべくブラウザが提供してくれている機能を使えるようにしてユーザーの選択肢を増やしてあげるほうがいいんじゃないかって思ってる派です。
ズーム機能ではダメなのか?
話を戻します。
文字サイズを大きくしたりするだけなら、ブラウザにはズーム機能があるのでそれで十分ではないか?という話です。
確かにそうですね。
ズーム機能を利用することで、文字も大きくなるのでそれでその目的自体は達成できると思います。
ただ、ズームでの拡大はレイアウトが変わったり、新しいタブを開くとそのズーム倍率がリセット(「設定」から変更している場合は除く)されたりします。
例えばGoogle Chromeのズーム機能だと、どんどん拡大していくと、レスポンシブWebデザインの画面幅を狭くしていったのと同じように、レイアウトがスマホの表示のようになったりします。

これは、このページをズーム機能で「150%」に拡大したスクリーンショットですが、ナビゲーションもハンバーガーメニューとなり、著者やSNSのシェアボタンの場所もスマホでの表示と同じレイアウトになっています。
これに対して、文字サイズの拡大機能は文字サイズだけが変わります。

こっちが文字サイズ変更機能で「極大」にしたスクリーンショットです。
文字サイズだけが変わってますね。
つまり、文字サイズ変更機能の場合は、レイアウトが変わらず文字サイズのみが大きくなっているのに対して、ズーム機能の場合はレイアウトも変更される可能性があります。
これが嫌なユーザーもいます。
「PCサイトのレイアウトの表示のままで見たい!」って。
現に僕の知り合いにズームでの拡大ではなく、ブラウザの文字サイズ変更機能を利用してる人がいます。
その方は、老眼で通常の文字サイズだと小さいので大きくして利用してます。
ズーム機能も試したことがあるらしいのですが、上記の理由からその方には合わなかったらしいです。
だから、文字サイズの拡大機能に対応してるサイトはありがたそうにしてました。
僕はリアルにこういう人を知ってるので、自分の作るサイトも文字サイズ変更機能を妨げないようにしようと思ってます。
そして何より、別に rem
や em
でfont-size
を指定したからといってズーム機能が使えなくなるわけじゃないんです。
ズーム機能は通常通り使えて、かつ文字サイズの拡大機能も有効になるんです。
となれば両方使えたらよくないですかね?
「大手のサイトや有名企業のサイトなども px
だ」
「そもそも、ズーム機能があれば十分だし、文字サイズ変更機能を使ってる人は3%くらいのユーザーだけだ」
という意見もあるかもしれません。
これに関しては・・・
「知らん。」
僕は大手の企業がこういう実装をしているからしたほうがいいとか、統計上その機能を使ってる人が少ないとか、そういうのはどっちでもよくて・・・
僕が「どんなユーザーにも情報を伝達できるメディア」というTVや雑誌やラジオなどの他のメディアではなかなか難しいWebの特性を活かしたいだけです。
だから、なるべくなら文字サイズ変更機能をはじめ、ブラウザが提供している機能を妨げたくはないし、目の前の知ってる人がその機能を利用してるのを実際に見てるので、自分が作るサイトは文字サイズ変更機能を使えるようにしておこうと思ってやってるだけなんです。
僕の勝手なこだわりです。
誰かに強要したいとかそういうことではありません。
px
を使われているサイトだって、色んな考えがあって px
を採用されてると思いますのでそれでいいと思うんです。
例えば、最近のAppleのサイトだって確かに px
で組んでますが、文字サイズ大きいですもんね。
主要なコンテンツは文字サイズを拡大しなくても見えるくらい、もともと文字サイズが大きいです。
それに、そもそもシンプルなシングルカラムのレイアウトが中心なので、ズーム機能でもそんなにレイアウトが変わらないです。
となると、確かに文字サイズ変更機能を使えなくても、ズーム機能で十分かもしれませんね。
現在、Shibajukuの課題やプロジェクトでは rem
や em
を使ってコーディングをしてもらってます。
ですが、実務ではみんなそれぞれの考えで最適な単位を選択して実装してもらったらいいと思っています。
rem
や em
のデメリットは?
僕にとっては、特にデメリットを感じないんですよね。
確かに px
で組めば、デザインカンプにある文字サイズの px
数をそのまま、font-size
に指定したらOKなのに対して、rem
や em
での指定は px
を rem
や em
に変換する必要があるので、多少は手間になります。
求めたいpx ÷ ルート要素の文字サイズ(デフォルト:16px)
という計算をしなければいけません。
でも、個人的にはそんな手間でもないと思うんですよね。
px | rem |
---|---|
10px | .625rem |
12px | .75rem |
14px | .875rem |
16px | 1rem |
18px | 1.125rem |
20px | 1.25rem |
24px | 1.5rem |
32px | 2rem |
40px | 2.5rem |
と、よく使う数値は覚えてますし、Sassとか使って関数とか作れば、自動で計算もできます。
@function pxToRem($size, $base-font-size: 16px) {
@return ($size / $base-font-size) * 1rem;
}
p {
font-size: pxToRem(14px); /* .875rem */
}
なんなら calc()
とか使ったらそのまま計算できます。(対応ブラウザは確認して下さい)
p {
font-size: calc(14 / 16 * 1rem );
}
あれなら、僕はやりませんが、html
要素に.625
remって指定して、body
要素に、font-size
のデフォルトの「medium
」を指定いておけば、14pxなら、1.4remと書けます。
html {
font-size: .625rem;
}
p {
font-size: 1.4rem; /* 14px */
}
li {
font-size: 1.2rem; /* 12px */
}
12pxなら、1.2remと書けますしね。
なので特に開発コストも増えないと思ってます。
「いやいや、『.(小数点)』が追加されているのと、『px
』は2文字に対して、『rem
』は3文字だろーが!開発コスト違うだろー!」
って言われたら、その通りです。
ごめんなさい。
でも、そんな変わりますかね・・・。
さっき例に挙げたスマホでの「PC版サイトを見る」機能に対応することと比べたら、そんなに大変なことではないと思うんです。
「PC版サイトを見る」の対応も難しいわけじゃないのですが、純粋なレスポンシブWebデザインでは対応できないので、ユーザーエージェントで表示を振り分けたりする必要があります。
そのことで、一つのコンテンツに対してのURLが複数できてしまい、そのコンテンツに対しての評価も分散されたり、デバイスごとにコンテンツを更新する必要があったり、まだ見ぬ新しいデバイスが登場したときに対応が必要だったり、色々な視点から考えなきゃいけないことがあるので、それに比べてたら、px
を rem
とか em
にするだけで対応できるのは、簡単かなと思うわけです。
「じゃあなんで書体の設定機能も簡単に対応できるのに対応してないの?」
確かに書体の設定機能も簡単に対応できますね。
書体の設定を有効にするには、CSSの font-family
で特定のフォント名を指定せず、「sans-serif
」などの総称フォント名か、何も指定しなければ対応できます。
body {
font-size: sans-serif;
}
めっちゃ簡単です。
ただ、僕がやってる案件のお客様のサイトの多くは、書体がサイトにどのような印象やイメージを持ってもらうかという点において重要な要素になることが多いです。
また、筆記体など視認性や可読性が低下する可能性がある書体の場合を除き、書体が違うからといって、文字サイズとは違い「見えない」とか「読めない」ってことまでにはなりにくいと思うんですよね。
ただこれは、ユーザーが書体を選べることはとても素敵なことだと思ってるので、未だに僕も悩んでる部分でもあります。
ですが、現状はそういった理由でfont-family
を設定しています。
なので僕としては特にデメリットもなく、ブラウザが提供してくれている文字サイズ変更機能を活用できるようになって、単純にユーザーの選択肢が増えるんだったらそうしたいなと思うわけです。
僕としてはこのあたりをどう設計するかもWebデザインだと思ってます。
いつでもどこでも rem
を使っているのか?
rem
を使えば、僕的には特にデメリットもなくブラウザの文字サイズ変更機能を有効にできるという話をしてきました。
じゃあ font-size
に「その他の単位は使わないのか?」と言われたらそうではありません。
CSSには rem
や em
の他にも ch
や ex
など、文字サイズをベースとした相対単位がありますし、small
や、large
などの絶対サイズのキーワードや、larger
, smaller
といった一段階多くするキーワードや、小さくするキーワードによる指定でも、文字サイズ変更機能を妨げずに文字サイズを指定することができます。
僕は基本rem
を使っていて、ところどころ em
。
他にも、文字サイズに対する相対値ではないですが vw
なんかも使ってます。
rem を主に使ってるところ
基本的に大きなブロックの font-size
には rem
を使って文字サイズを指定しています。
あとは、文字サイズじゃないですが上下の margin
など文字周りの余白も rem
で組んでます。
ブラウザの文字サイズが拡大されたり、文字のサイズが大きくなった時に、文字の上下の余白が小さいまんまだと結局読みづらいですからね。
だから、文字サイズが大きくなったらそれに応じて余白も多くなるように上下の margin
や、視認性や可読性に繋がる余白は rem
で指定しています。
em を主に使っているところ
大きなブロックの中で登場するインラインの要素には em
を使うことがあります。
例えば、small
要素なんかには僕はよくem
を使います。
small
要素は細目テキストなどを表す要素ですが、多くの場合p
要素とか、li
要素などの文章の中の一部として使うことが多いです。
<p>
僕は哺乳類だ。
<small>※ 諸説あります</small>
</p>
こういうケースの時は、だいたいp
要素に直接挟まれている部分より、small
要素部分を少し小さく表示したいことが多いです。
もちろん rem
などで指定しても文字サイズを小さく出来ます。
small {
font-size: .75rem; /* 12px */
}
このようにすると、p
要素に直接挟まれている部分は文字サイズはデフォルトの16px ブラウザの文字サイズ設定が中の時 で、small
要素部分が12pxになります。
じゃあ他の箇所で、li
要素の中でsmall
要素が同じように使われていたとして、
<ul>
...
<li>
僕は両生類だ。
<small>※ 諸説あります</small>
</li>
</ul>
で、仮にもしli
要素の文字サイズも小さかったとしたら?
li {
font-size: .75rem; /* 12px */
}
small {
font-size: .75rem; /* 12px */
}
これだと、新たにsmall
要素にCSSを追加しないと、small
要素で囲まれたところは、li
要素と同じ文字サイズになります。
でもこれを em
で指定していたら?
li {
font-size: .75rem; /* 12px */
}
small {
font-size: .75em; /* 12px × 0.75 = 9px(10px) */
}
親要素の文字サイズからの0.75倍になるので、9pxという計算になります。
ま、実際はブラウザには最小文字サイズの設定がされていて、例えばGoogle Chromeだと、デフォルトの最小文字サイズが 10px になるので、その場合はこのsmall
要素の範囲は 10px として表示されます。
でも、こうやって指定しておくと親要素に大きさに応じて文字サイズが変わってくれるので、このようなケースに em
はとても役立ちます。
vw を主に使っているところ
メインビジュアルのキャッチコピーなどの大きな文字には、vw
なんかもよく使います。
- vw
- ビューポート(ブラウザ)の幅の 1% を1とする単位
ただし、vw は文字サイズに対する相対値ではなく、ブラウザの幅に対する相対値なので、文字サイズ変更機能が効きません。
でも、メインビジュアルなどの大きな文字は、すでにそれ以上拡大しなくても十分大きな文字サイズになってることが多いと思います。
そこまで、rem
やem
なんかで組むと、そこから更に文字が大きくなって、かえって読みにくくなることもあります。
むしろメインビジュアルなどは、デザインにもよりますがブラウザの幅に応じて画像なども大きくなっていくので、その画像幅が大きくなるのと同じように、文字サイズも大きくなったほうがよかったりもします。
こんな時に重宝するのが vw
です。
vw
はブラウザの幅に応じて変化する単位なので、ブラウザが可変するたびにサイズが変わります。
仮に、ブラウザが1000pxの幅で開いてる時の 1vw
は、10px という計算になります。
そして、ブラウザの幅が 2000pxまで広がったときには、20px になるんです。
このようにブラウザの文字サイズ変更機能を必要とせず、幅に応じて変化したほうがいい箇所に関しては vw
を使ったりしています。
スマホサイトはどうなのか。
スマホの場合もピンチインやピンチアウトといった拡大縮小の他に、例えば、iPhoneのSafariにはズーム機能がありますし、iPhoneのGoogle Chromeにもテキストサイズの拡大機能があります。

実は、どちらも px
で 組んでても機能します。
そういう意味では px
でも rem
でもどちらでもいいのかもしれませんね。
ですが、vw
は注意ですよ。
vwはブラウザの幅に対する相対値だからか、iPhone の Safari では文字サイズが変わらないです。(ピンチインやピンチアウトによる拡大縮小は大丈夫です)
iPhone の Google Chromeではちゃんと文字サイズが大きくなります。
僕の使い分けとしては、基本的な段落などの文章にはPCと同じく、rem
や em
を使って、見出しやキャッチコピーなど、もうそれ以上大きくしなくても読めるくらい大きい文字には vw
を使ってたりします。
スマホにはいろんな種類、大きさのデバイスがあるので、それぞれのデバイスの幅に応じてブレークポイントを作ってfont-size
を調整するのはちょっと大変で、サイトを公開後も新たなサイズのデバイスが登場するたびにブレークポイントを追加する必要が出てくる可能性もあります。
だから、デバイスの幅に応じて変化してくれる vw
を使ってコーディングしてると便利なんですよね。
まとめ
という事で僕としては、
ブラウザが用意している機能をとくにデメリットもないのに使えなくするのは個人的に嫌だというのと、自分の知ってる人がブラウザのズーム機能ではなく、文字サイズ変更機能を必要としているのを見てたので、僕は「もうpx
でいいんだよ」やrem
を使ってる人を「rem信者」と言われてる今でも rem
や em
などと言った相対値で文字サイズを指定しています。
また、相対値と言ってもいろんな単位があるので、その時々で状況に合わせて使い分けると便利ですよ。
この記事は決して「文字サイズにpx
を使うのは良くない」とか、「みんなも rem
使おうよ」とか言いたい記事ではなく、僕はそれでも相対値を使ってるよってだけの記事でした。
サロンのライブ授業でもこんなことをつらつら喋ってたので、font-size
の説明だけで30分も授業してました。
じゃーねー。