CSSにおけるさまざまな単位 第1回 フォントに関する単位

CSSで使う単位のうち、フォントに関する単位を取り上げます。em、rem、lh、rlhなど、実務でもよく使われる単位について見てみましょう。

発行

著者 坂巻 翔大郎 フロントエンド・エンジニア
CSSにおけるさまざまな単位 シリーズの記事一覧

はじめに

CSSにはさまざまな単位が存在します。pxremといった実務でよく扱う単位もあれば、HzkHzのようにまだブラウザ実装がなく利用できない単位もあります。 本シリーズでは、CSSで使われる単位の意味や利用方法について解説します。

CodeGridでは、すでに「仕様書の読み方 CSSプロパティ編 最終回 | 型と単位を押さえる」という記事で、CSSに登場する型と、ある程度の単位について解説されていますので、本シリーズを読みはじめる前に一読しておくとより理解が進みます。今回は、以前のシリーズでは触れられなかった単位や新しく利用できるようになった単位についても丁寧に解説していきます。

CSSにおける単位の基礎知識

まず知っておきたいのは、CSSにおける単位には、何かしらの具体的なものに対しての絶対値と、相対値の2つの種類があるということです。「何かしらのもの」とは、文字の大きさや、要素・画面の幅、解像度などさまざまです。

相対的な単位には、emremなどがあり、これらは親要素や基準となる要素に対しての相対的な値を指定できます。一方、絶対的な単位には、pxcminなどがあり、これらは画面や印刷物などの物理的な値を指定できます。

単位を利用するときは、数値のあとに続けて単位を記述する必要があります。たとえば16pxなどと記述しますが、16 pxのように数値と単位の間が空いていたりすると無効な値となります。また、単位なしの数値は、margin: 0;のように記述することがありますが、プロパティによっては単位が必須になる場合もあります。

パーセンテージ(%)は「単位」なのか?

パーセンテージ(%)は、いろいろなものに対する相対的な値ですが、CSSにおける単位は「親要素の文字のサイズに対する」単位(em)や「ビューポートの幅に対する」単位(vw)のように、具体的に何に対して相対的/絶対的であるか明確になっています。パーセンテージは利用するプロパティによって参照するものが定義されており、いろいろなものに対する相対的な値となります。そのため、仕様書の中では「単位」としては扱われておらず「パーセンテージ値」となっています。

フォントに関係する単位

CSSにはさまざまな単位があると冒頭で述べましたが、まず今回はフォントに関する単位について説明します。

フォントに関係する単位には、emremexchなどがあります。これらはフォントに関して、相対的な値を指定できる単位です。

単位 意味
em 親要素のフォントサイズに対する相対的な値
ex フォントの小文字の高さ(x-height)に対する相対的な値
cap フォントの大文字の高さ(cap-height)に対する相対的な値
ch フォントの半角文字"0"(U+0030)の幅*に対する相対的な値
ic フォントの全角文字"水"(U+6C34)の幅*に対する相対的な値
lh 要素の行の高さ(line-height)に対する相対的な値

*注:幅

ここでいう「幅」とは、文字の開始位置から、次の文字の開始位置までの長さのことで、「送り幅」とも呼ばれます。横書きの場合は文字の横幅、縦書きの場合は文字の高さになります。

この中で利用頻度が高いものはemlhでしょう。excapchicについては、あまり使われることはありませんが、フォントに関する単位として覚えておきましょう。

em

emは親要素のフォントサイズに対する相対的な値です。親要素のフォントサイズが変化すればそれに応じてemを指定した要素のフォントサイズも変化します。

<p>
  この本文のフォントサイズは16pxです。
  <small>ここの注釈のフォントサイズは0.75emです。</small>
</p>
p {
  font-size: 16px;
}
small {
  font-size: 0.75em;
}

この場合、small要素のフォントサイズは親要素のフォントサイズ16px1emとしたときの0.75emとなり、計算すると16px * 0.75 = 12pxとなります。

最初のsmall要素の中に、さらにsmall要素を入れてみるとどうなるでしょうか。

<p>
  この本文のフォントサイズは16pxです。
  <small>
    ここの注釈のフォントサイズは0.75emです。
    <small>ここの注釈のフォントサイズは0.75emです。</small>
  </small>
</p>

small要素にネストされた子であるsmall要素は変わらず0.75emですが、その親であるsmall要素のフォントサイズは12pxとなっているため、12px1emとしたときの0.75emとなります。

  • p要素:16px(※A)
  • 親のsmall要素:16px(※A) * 0.75 = 12px(※B)
  • ネストされた子のsmall要素:12px(※B) * 0.75 = 9px

lh

lhは、その要素のline-heightプロパティの計算値を1lhとします。

<p>3行分の高さを確保した要素</p>
p {
  font-size: 16px;
  line-height: 1.5;
  height: 3lh;
  color: #fff;
  background-color: black;
}

この場合、line-height1.5であるため、line-heightの計算値は16px * 1.5 = 24pxとなります。そのため、height3lh72pxとなります。

lh単位は、テキストや要素の垂直方向の間隔を一貫して整えるバーティカルリズムを取り入れたレイアウトを行う際に便利です。詳しくは後述します。

ex・cap・ch・ic

exは、xなどの小文字の高さで、capは、Xのような大文字の高さです。テキストに並ぶアイコンの高さを小文字や大文字の高さに揃えるというような場合に使えるでしょう。

chは、0(半角数字のゼロ、U+0030)の幅を表します。等幅フォントを使えば、英語の文章などで、1行の幅を30文字(30ch)にするということもできますが、使い所は限られるかもしれません。

icは、全角文字の(U+6C34)の幅を表します。漢字が主な中国語の文章などで、1行の幅を30文字(30ic)にするような場合に利用できそうですが、日本語では、漢字や英語、半角数字・カナなどさまざまなものが入り交じるため、特定の文字分の幅にする使い方は向いていないかもしれません。

次のデモでは、icを使って全角一文字分の幅を確保しています。それぞれの行でフォントが異なるため、1icあたりの幅が異なることがわかります。

<p>水あいうえお(何もしてないもの)</p>
<p class="futo">水あいうえお(太くしたもの)</p>
<p class="hoso">水あいうえお(細くしたもの)</p>
/* https://github.com/adobe-fonts/source-han-sans/blob/master/LICENSE.txt */
@font-face {
  font-family: "mizu-futo";
  src: url("assets/fonts/mizu-futo.woff");
}
@font-face {
  font-family: "mizu-hoso";
  src: url("assets/fonts/mizu-hoso.woff");
}
body {
  font-size: 40px;
  margin: 0;
}
p { margin-left: 1ic; }
.futo { font-family: "mizu-futo"; }
.hoso { font-family: "mizu-hoso"; }

1行目は特に何もしていない状態、2行目(.futo)は水を横長にしたフォント、3行目(.hoso)は水の幅を狭くしたフォントを使用しています。

基準となる「水」の幅が違えば、1icの幅もそれに応じるため、それぞれの行でのmargin-left: 1ic;が指す大きさが異なることがわかります。

こういった、1文字分の幅を確保したい場合に、1emを使うことがありますが、emはあくまでフォントサイズが基準になるため、全角文字の幅を基準としたい場合はicを使うとよいでしょう。

「水」の幅が基準

icで全角文字の「水」の幅が基準になっているのは、縦書きでも横書きでも長さが変わらずに安定している、「水」は漢字の入るフォントには基本的に入っている、などの理由があるそうです。

ただ、フォントやタイポグラフィにおいて、漢字を表す代表の文字としては「永」が使われることが多いです。これは、「永字八法」という、点・はね・はらいなど、書に必要な技法8種がすべて含まれているためです。icは「単位」ですので技法が含まれているかどうかは関係ありませんが、代表的な漢字の「永」をicでも使うほうが望ましい、という議論もあります。

とはいえ、「水」でも「永」でも寸法が違うことはないようです。もしicの幅の基準が「永」になったとしても、長さの単位としては同じように使えるでしょう。

ルート要素のフォントに関係する単位

ルート要素とは、最上位の要素のことで、HTML文書においてはhtml要素がルート要素となります。

そのルート要素を基準とする単位はrから始まります。

単位 意味
rem ルート要素のフォントサイズに対する相対的な値
rex ルート要素の利用可能な最初のフォントの小文字の高さ(x-height)に対する相対的な値
rcap ルート要素のフォントの大文字の高さ(cap height)に対する相対的な値
rch ルート要素のフォントの半角文字"0"(U+0030)の幅に対する相対的な値
ric ルート要素のフォントの全角文字"水"(U+6C34)の幅に対する相対的な値
rlh ルート要素の行の高さに対する相対的な値

emであれば「親要素のフォントサイズ」を意味していましたが、remは「ルート要素のフォントサイズ」を意味します。

ルート要素を基準にできるため、親要素のフォントサイズなどが変わっても、影響を受けません。

rem

h1 {
  font-size: 2rem;
}
p {
  font-size: 1rem;
}

ブラウザのデフォルトのフォントサイズは16pxですので、h1要素のフォントサイズは32pxp要素のフォントサイズは16pxとなります。

ルートを基準にしているため、ルート要素ではない親要素のフォントサイズが変わっても、remで指定した要素のフォントサイズは変わりません。

rememはどちらか一方を使えば良いというわけではなく、特性を理解して使い分けることが重要です。

rlhを使い、行間を基準にした値をレイアウトに取り入れる

rlhは、ルート要素のline-heightプロパティの計算値を1rlhとするものです。

要素間の高さ、マージン、パディングなどでrlhを利用すれば、ルート要素の行間を基準にして設定できるため、見た目のバランスや読みやすさを整えられます。

次のコード例を見てみましょう。

<h1>h1の見出しです。</h1>

<p>テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</p>

<p>テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</p>

<p>テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</p>
html {
  font-size: 16px;
  line-height: 1.5;
}

body {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: repeat(3, auto);
  gap: 1rlh;
  margin: 0;
  padding: 1rlh;
  background-image: linear-gradient(rgba(50, 50, 50, 0.2) 1px, transparent 1px);
  background-size: 100% 1rlh;
}

h1, p {
  box-sizing: border-box;
  margin: 0;
  padding: 1rlh;
  background-color: rgba(0, 0, 0, 0.1)
}

h1 {
  grid-column: span 2;
  line-height: 1rlh;
}

h1 + p {
  grid-column: span 2;
}

デモを見ると、背景に罫線が引かれており、その罫線の間隔は1rlhになっています。そして見出しや本文は、その罫線に沿って配置されていることがわかります。

このように、rlhを利用することで、ルート要素の行間を基準にした値をレイアウトに取り入れられます。

ここまでのまとめ

CSSに登場するさまざまな単位の中から、まずはフォントに関係する単位について解説しました。

多くの単位がありますがその中でも、emremlhrlhについては実務でも便利に活用できる単位です。フォントに関するすべての単位を使うことはないかもしれませんが、それぞれの特徴を理解しておきましょう。