[CSS] remを使用したline-heightのベストプラクティス

ウェブページの行の高さ・行間を良い感じに制御したいと考えたとき、難しいと感じるのは私だけでしょうか。そんな私が行き着いた2025年現在の line-height のベストプラクティスを紹介します。

line-height に rem を使いたい

line-height はフォントサイズに対する割合で設定するのが一般的です。

body {
  line-height: 1.75; /* フォントサイズが 16px のとき行の高さは 28px で行間は 12px */
}

しかし、フォントサイズを大きくした場合、行間が広くなりすぎることがあるため、font-size と共に line-height も設定する必要が出てきます。

h1 {
  font-size: 2em;
  line-height: 1.375; /* フォントサイズが 32px のとき行の高さは 44px で行間は 12px */
}

この煩わしさを解消するために rem を使用します。line-height の値が単位付きだと子孫要素への継承時に問題が起こるため、要素毎に計算させるようにします。

* {
  line-height: calc(1em + 0.75rem); /* 1rem が 16px のとき行間は常に 12px */
}

このままでは line-height を変更しても子孫要素には継承されません。

main {
  line-height: calc(1em + 1rem); /* main要素の行間は 16px だけど子孫要素は 12px のまま */
}
aside {
  line-height: calc(1em + 0.5rem); /* aside要素の行間は 8px だけど子孫要素は 12px のまま */
}

そこで、行間 (leading) を変数にし、変数を子孫要素に継承させることで、この問題を回避します。

html {
  --leading: 0.75rem; /* デフォルトの行間は 12px */
}
* {
  line-height: calc(1em + var(--leading));
}
main {
  --leading: 1rem; /* main要素とその子孫要素の行間は 16px */
}
aside {
  --leading: 0.5rem; /* aside要素とその子孫要素の行間は 8px */
}

ここまでが rem を使用した line-height の基礎になります。

line-height に rem を使った際のデメリット

line-heightrem を使用することで、フォントサイズに左右されない行の高さ・行間を設定することができました。しかし、実際に運用してみるといまいち使い勝手が良くありません。

その理由は、フォントサイズを大きくした際に行間が広くなるということはなくなりますが、フォントサイズを小さくした際にも行間がそのままなので、フォントサイズに対して行間が広くなるためです。

main {
  --leading: 0.75rem;
  font-size: 1rem;
  /* leading : font-size = 3 : 4 */
}
aside {
  --leading: 0.75rem;
  font-size: 0.75rem;
  /* leading : font-size = 1 : 1 */
}

そのため、フォントサイズと行間の割合を保ちたい場合などには、そのつど計算して行間を変更する必要があります。

main {
  --leading: 0.75rem; /* 1em (1rem) の 0.75倍 (3/4文字分) の行間 */
  font-size: 1rem;
}
aside {
  --leading: 0.5625rem; /* 1em (0.75rem) の 0.75倍 (3/4文字分) の行間 */
  font-size: 0.75rem;
}

行間を分解して使い勝手を良くする

--leading--lead-size, --lead-ratio, --lead-scale に分解して計算の手間がなくなるよう手を加えます。

html {
  --lead-size: 1rem; /* --leading のベースとなるフォントサイズ */
  --lead-ratio: calc(3 / 4); /* フォントサイズに対する行間の割合 */
  --lead-scale: 1; /* --leading の縮小比 (拡大比) */
}
* {
  line-height: calc(1em + var(--leading, var(--lead-size) * var(--lead-ratio) * var(--lead-scale)));
}
main {
  --lead-size: 1rem;
  font-size: 1rem;
}
aside {
  --lead-size: 0.75rem;
  font-size: 0.75rem;
}
h1, h2, h3, h4, h5, h6 {
  --lead-scale: calc(1 / 2); /* 行間を通常の 1/2 に縮小 */
}

このように、font-size--lead-size に同じ値を設定するだけで、行間の割合を一定に保つことができます。また、ウェブページ全体の行間を調整したい場合は --lead-ratio を、特定の要素の行間を調整したい場合は --lead-scale を変更することで実現できます。

CodePen

See the Pen line-height using rem by nov (@numerofive) on CodePen.

垂直方向の余白は基本 rem で設定するという考え方が「line-height にも rem を使いたい」という発想の根本になっています。余白の単位を rem に統一することで、そこそこ基調のとれたバーティカルリズムになるのでは?と思ってます。

関連記事