CSSの「font-size: 20px;」という指定について調べたら奥が深かった

CSSで普段なんの気無しに使っている「font-size: 20px;」といった指定の挙動を細かく調べてみたら、想像を遥かに超える複雑さでした。調べたことや実験結果を記録します。

CSSで文字の大きさを指定するのに「font-size: 20px;」といった指定をよく使います。

このとき、具体的に何が20pxなんだろう?と疑問に思い、仕様を調べたりキャプチャを撮って実験してみました。

調査方法について

HTMLとCSSをCodePenで実装し、ブラウザの画面キャプチャを撮影してどのような大きさで表示されるかを調べていきます。

MacBookのChromeで調査・検証を行っています。

キャプチャ内に記載する大きさは、実際の測定値を2で割った値を記載しています。(検証に使用したMacBookのデバイスピクセル比が2のため)

まずは基本の確認

p要素の中にspan要素を入れ、その中にテキストを入力し、どのように表示されるかを確認してみます。

テキストは、日本語文字のみと、英数字のみの2種類を用意します。

フォントファミリーには游ゴシック、フォントサイズには20pxを指定します。

pspanの大きさがわかるよう、それぞれに異なる背景色を指定しています。

コード

html
<p class="YuGothic">
  <span>あのイーハトーヴォのすきとおった風、</span>
</p>
<p class="YuGothic">
  <span>The quick brown fox jumps over the lazy dog, 1234567890.</span>
</p>
css
p {
  background-color: #78BFAB;
  font-size: 20px;
}

span {
  background-color: #F2A25C;
}

.YuGothic {
  font-family: "游ゴシック", YuGothic;
}

結果(ブラウザ表示のキャプチャ)

1

spanの高さが20px、pの高さが30pxとなりました。

font-size: 20px;と指定した場合、文字の高さが20pxとなり、p1行分(行ボックス)の高さは、font-sizeline-heightの組み合わせで決まります。

今回の例ではpline-heightを指定していないので、CSSの仕様として、デフォルト値のnormalとなります。

line height normal

これらの結果、Chromeはline-heightの値を1.5と解釈したようで、font-sizeの20pxに1.5をかけた、30pxがpの高さとなりました。

line-heightの指定を追加する

上記の例に、line-heightの指定を追加してみます。

css
p {
  background-color: #78BFAB;
  font-size: 20px;
  line-height: 1.6;
}

//(省略)

結果(ブラウザ表示のキャプチャ)

2

pの高さが、font-sizeの20pxに1.6をかけた32pxとなり、想定通りの結果になったかと思います。

ここまでの結果から、私の理解としてはざっくりと以下のようなものになりました。

  • font-sizeの数字は行の中のインライン部分の高さになるんだなあ
  • 1行(行ブロック)の高さは、font-sizeの値とline-heightの値で決まるんだなあ
  • line-heightは、何も指定しなかったらnormalになって、normal1.5と同じ結果になるんだなあ

普段CSSを扱ううえでの理解はだいたいこんな感じで十分かと思います。

ただ、念のため他の書体も調べてみたところ、思わぬ複雑さに遭遇することとなりました。。

フォントファミリーを変更して確認する

Macで手軽に検証できる書体で同じ検証を行ってみた結果は以下のようになりました。

3

table1 ※単位はpx

上記の通り、フォントファミリーのOsakaとTimesでは、spanpの高さが他と異なる値になりました。

ヒラギノ角ゴシックとOsakaの表示をよく見てみると、ディセンダー部分(j,p,gなどの、下にはみ出している部分)に違いが見られます。ヒラギノはディセンダーがspanの背景色を突き抜けていますが、Osakaはディセンダーもspanの背景色の中に入っています。

5

さらに興味深いのは、Timesの日本語部分です。Timesは日本語文字を持たないフォントファミリーのため、日本語部分にはブラウザのデフォルト、この例ではヒラギノ角ゴシックが適用された状態になっています。

最終的に同じフォントファミリーが適用されているにもかかわらず、Timesを指定した場合と、ヒラギノ角ゴシックを指定した場合で、spanの高さが2px異なるという結果になりました。

4

このあたりは、CSSの高さ計算の仕様を詳しく見てみる必要がありそうですので、またの機会に調査しようと思います。

フォントサイズを30pxにして検証する

同様に、font-sizeを30pxにしたものの大きさも測定してみました。

table2 ※単位はpx

20pxのときと大体同じような結果になりました。

ブラウザを変えて検証する

Chrome、Safari、Firefoxそれぞれの差異がないか検証しました。

結論から言うと、Firefoxのみ差が出る結果となりました。

chrome safari firefox

table3

Firefoxだけ、spanの高さが0.5pxだけ(デバイスピクセル比2のMacBook上で1px分だけ)高く表示されていました。

検証から得た気付き

今回の検証により、以下の気付きを得ました。

  • 文字の大きさを1px単位でコントロールすることは難しい
  • font-sizeだけの指定では、font-familyによって1行の高さが変わることもある
  • font-sizeline-heightを指定していれば、font-familyやブラウザによる1行の高さの差異は少ない

ということで、日頃CSSを書くうえではfont-sizeline-heightを必ず一緒に指定し、行ブロックの高さが環境によって変わらないようにしていくのが良さそうです。

今回の検証では仕様を完全には解明できていませんが、いつか詳しく調べて見たいと思います。

検証に使用したソースコード(CodePen)はこちら

以上です。最後までお読みいただきありがとうございました。