デザインと実装をつなぐウェブタイポグラフィ設計入門

# はじめに

タイポグラフィ（typography）とは、文字を読みやすく、美しく見せるための技術・デザインのことです。

「ウェブデザインの95%はタイポグラフィである」[^1]とも言われますが、適切に設計された文字情報はユーザーの目を引きつけ、ウェブページの内容を理解しやすくします。

ウェブにおけるタイポグラフィは一見するとデザイナーの領域のように思われがちですが、実際にはフロントエンドエンジニアがCSSという実装手段を用いてそのデザインを実現します。CSSを書くという行為そのものが、タイポグラフィに関するさまざまな意思決定をしていく重要なプロセスであると言えます。

本記事では、ウェブタイポグラフィ設計の基本的な考え方と、いくつかの具体的な実装方法を紹介します。この記事がよりよいタイポグラフィを実現するヒントとなり、日々の制作業務の一助となれば幸いです。

[^1]: https://ia.net/topics/the-web-is-all-about-typography-period

# 1. ウェブタイポグラフィの基礎

ウェブタイポグラフィの基礎であり根幹となる「フォントサイズ」と「行間」について考えます。

## 1.1 ブラウザのデフォルトスタイルを知る

### デフォルトのフォントサイズと行間

CSSが一切書かれていないウェブページにおいて、ブラウザはどのようにテキストを表示するのでしょうか。

```html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>

  <p>テキストテキスト</p>
  
  <h1>テキストテキスト</h1>
  <h2>テキストテキスト</h2>
  <h3>テキストテキスト</h3>
  <h4>テキストテキスト</h4>
  <h5>テキストテキスト</h5>
  <h6>テキストテキスト</h6>

</body>
</html>
```

<p class="codepen" data-height="300" data-default-tab="result" data-slug-hash="XJraPKB">
  See the Pen <a href="https://codepen.io/shouchida/pen/XJraPKB" rel="nofollow noopener" target="_blank">
  qiita_c382cf78f8ffe6fbe65b_03</a> by Sho Uchida (<a href="https://codepen.io/shouchida" rel="nofollow noopener" target="_blank">@shouchida</a>)
  on <a href="https://codepen.io" rel="nofollow noopener" target="_blank">CodePen</a>.
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

下記の表は、最低限のマークアップをしたHTMLページをGoogle Chrome（131.0.6778.205）で表示した時のフォントサイズと行間の値です。

|要素|font-size|line-height|
|--|--|--|
|p (body)|(16px)|(1.5)|
|h1|2em (32px)|(1.5)|
|h2|1.5em (24px)|(1.5)|
|h3|1.17em (18.72px)|(1.442308)|
|h4|1em (16px)|(1.5)|
|h5|0.83em (13.28px)|(1.581325)|
|h6|0.67em (10.72px)|(1.399254)|

Google Chromeでは、body要素のフォントサイズはデフォルトで16pxとなっており、見出し（h1〜h6要素）は、body要素のフォントサイズを基準にした相対値（em）によって大小が設定されています。行間（line-height）は初期値がnormalに設定されていますが、数値としてはおおよそ1.5となっていました。

これらのスタイルは、ブラウザやフォントによって微妙に異なる場合がありますが、基本的な傾向はほぼ共通しています。

- font-sizeは全ブラウザで16pxを基準とする
- line-heightはブラウザごとに微差はあるが、おおむね1.4〜1.6の間に収まる

これらのルールが、「ブラウザが規定する標準的なタイポグラフィ」と言えるのではないでしょうか。

## 1.2 フォントサイズ（font-size）の設計

### ウェブタイポグラフィにおけるemの役割

emは親要素のフォントサイズを基準にした相対単位です。先ほどGoogle Chromeの例で見たように、ブラウザは見出し要素などにem単位を使い、フォントサイズを表現しています。

「基準となるフォントサイズがまずあり、相対的に他のサイズを定義していく」
「基準が変われば、それに応じて他のサイズも変化していく」
という仕組みになっていることがわかります。

柔軟性のあるem単位ですが、親要素の指定に影響されるため、CSSの継承によって計算が複雑になり、フォントサイズの把握が難しくなる場合があります。

```html:ネストされたリスト要素
<ul>
  <li>
    テキスト
    <ul>
      <li>テキスト</li>
      <li>テキスト</li>
    </ul>
  </li>
  <li>テキスト</li>
  <li>テキスト</li>
</ul>
```

```css
ul {
  font-size: 0.9em;
  /* 1階層目のul要素は 16px * 0.9 = 14.4px */
  /* 2階層目のul要素は 16px * 0.9 * 0.9 = 12.96px */
}
```

<p class="codepen" data-height="300" data-default-tab="result" data-slug-hash="yyBoxMv">
  See the Pen <a href="https://codepen.io/shouchida/pen/yyBoxMv" rel="nofollow noopener" target="_blank">
  qiita_c382cf78f8ffe6fbe65b_03</a> by Sho Uchida (<a href="https://codepen.io/shouchida" rel="nofollow noopener" target="_blank">@shouchida</a>)
  on <a href="https://codepen.io" rel="nofollow noopener" target="_blank">CodePen</a>.
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

### remによる一貫性のある設計

このような課題を解決するために、ルート要素（html）のフォントサイズを基準にするremが有効です。remを使用すると、親子関係や継承に左右されないフォントサイズを保つことができます。

```html:ネストされたリスト要素
<ul>
  <li>
    テキスト
    <ul>
      <li>テキスト</li>
      <li>テキスト</li>
    </ul>
  </li>
  <li>テキスト</li>
  <li>テキスト</li>
</ul>
```

```css
ul {
  font-size: 0.9rem;
  /* 1階層目のul要素は 16px * 0.9 = 14.4px */
  /* 2階層目のul要素も 16px * 0.9 = 14.4px */
}
```

<p class="codepen" data-height="300" data-default-tab="result" data-slug-hash="bNbrxaR">
  See the Pen <a href="https://codepen.io/shouchida/pen/bNbrxaR" rel="nofollow noopener" target="_blank">
  qiita_c382cf78f8ffe6fbe65b_03</a> by Sho Uchida (<a href="https://codepen.io/shouchida" rel="nofollow noopener" target="_blank">@shouchida</a>)
  on <a href="https://codepen.io" rel="nofollow noopener" target="_blank">CodePen</a>.
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

基準が明確なことで実装結果がわかりやすいrem単位は、現代ではもっとも使用頻度の高いフォントサイズ単位なのではないでしょうか。

### px（絶対値）による指定

絶対単位であるpxを使用した場合、確実にそのフォントサイズに固定されます。単純にデザイン再現だけを考慮した場合には便利な単位ですが、ブラウザの文字サイズ変更機能などによる相対的なサイズ変化を一切許容しなくなります。

下記のようなfont-size指定は避けるべきでしょう。

```css
/* NG */
html {
  font-size: 16px;
}
```

「各ブラウザのデフォルトフォントサイズが16pxに統一されていなかった時代」にはよく見られた指定です。現在は不要と言えるでしょう。

先ほども述べたように、ユーザーによる文字サイズ変更なども無効にしてしまうため、アクセシビリティ上の問題が生じる場合があります。

### emとremをどう使い分けるか

何らかのコンポーネントのフォントサイズをCSSで決定する際、「それが何に起因するサイズ変化なのか」を考え、emとremを使い分けます。

ページ全体に対する相対サイズ指定であればremを、各コンポーネント内での相対サイズ指定であればemを使うのがよいでしょう。

下記の例では金額表記の「円」だけを小さくしています。em単位を使うことで「数字部分の半分のサイズにする」という意図が明確になり、仮に金額表記全体（`.price`）のフォントサイズが変動した場合も `.yen` のCSS指定に手を加えることなくバランスを保つことができます。

```html
<p class="price">29,800<span class="yen">円</span></p>
```

```css
.price {
  font-size: 2rem;
}

.yen {
  font-size: 0.5em; /* 0.5倍のサイズ */
}
```

<p class="codepen" data-height="300" data-default-tab="result" data-slug-hash="dPbzqdy">
  See the Pen <a href="https://codepen.io/shouchida/pen/dPbzqdy" rel="nofollow noopener" target="_blank">
  qiita_c382cf78f8ffe6fbe65b_03</a> by Sho Uchida (<a href="https://codepen.io/shouchida" rel="nofollow noopener" target="_blank">@shouchida</a>)
  on <a href="https://codepen.io" rel="nofollow noopener" target="_blank">CodePen</a>.
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## 1.3 行間（line-height）の設計

### サイト全体の基準を決める

行間の設計においては、まずはそのページやサイト全体の基準となるline-heightを決めておき、調整が必要なコンポーネントに対してのみ追加でline-heightを指定する、という考え方で進めるのがよいでしょう。

ブラウザデフォルトのスタイルも考慮し、日本語サイトの場合は1.5程度のline-heightにしておくことが妥当と考えます。

```css
body {
  line-height: 1.5;
}
```

一方で、下記のようなline-height指定は避けるべきでしょう。

```css
/* NG */
body {
  line-height: 1;
}
```

line-heightによって発生する「余白」を嫌ったリセット的な手法として、このような指定がされているサイトも稀に見られます。

このようなスタイルがbody要素に設定されている場合、実質すべてのコンポーネントに対して個別にline-height指定をする必要があり、保守性や拡張性に問題が生じます。

### 日本語と英語におけるline-height

日本語は文字の構造上、英語よりも行間が狭く見えます。多言語サイトを制作する際、日英で同じline-height指定をすると不自然になる場合もあるため、言語ごとに必要に応じて調整しましょう。

```css
body {
  line-height: 1.5;
}

/* 英語サイト */
html[lang="en"] body {
  line-height: 1.3;
}
```

### 見出しなど大きなテキストのline-height

フォントサイズが大きい場合には行間が広く見えるため、サイト基準のline-heightよりも小さな値を個別指定するとよいでしょう。

```css
body {
  line-height: 1.5;
}

h1 {
  line-height: 1.2;
}
```

# 2. 実践的なスタイル設計

タイポグラフィの完成度を左右するのは、ウェブサイト全体に頻繁に使われる「普通のテキスト」の設計です。この章では、テキストリンク、本文、見出しといった主要な要素に焦点を当て、具体的なスタイル設計の手法を解説します。

## 2.1 テキストリンク

純粋なa要素で表現されるテキストリンクは、もっともシンプルなコンポーネントと言えます。a要素はサイト内でさまざまな形で使われるため、基本となるスタイルをきちんと定義しておくことが重要です。

テキスト色が変わるのか、下線が付くのか、hover時の挙動はどうなるか、など、デザインカンプに具体的なリンクスタイルが記載されていない場合でも、デザイナーとすり合わせをしてスタイルを定義していきます。

デフォルトのa要素のスタイルを後から変更すると、拡張されたa要素（ボタンやカードなど）のスタイルにも影響する可能性があるため、事前の設計が特に重要です。

「普通のテキストリンク」の設計を後回しにした結果、個別にclassを振る必要が出てくるなど、サイト運用に支障がでることが考えれます。

```html:普通のテキストリンクに個別にclassを振っている例
<p>テキストテキスト<a href="#" class="textLink">普通のテキストリンク</a>テキストテキスト</p>
```

## 2.2 本文

「本文」（ほんぶん・ほんもん）は、ウェブサイトの大部分を構成する主要な文章です。「文」「段落」「箇条書きリスト」「画像」などで構成されます。

英語では「body」や「text」と表現されるようです。

要するに、サイト内のどこにでもある「普通のテキスト」ですが、これらの要素のスタイル設計がサイト全体のタイポグラフィ品質を左右すると言ってよいでしょう。

### 段落のスタイル

まずは本文に登場する「普通の段落」（p要素）のスタイルを検討します。段落間には余白があることが一般的です。

ここでは「本文」を表すコンテナコンポーネントを作り、その内部の「普通の段落」のスタイルを指定します。

```html
<div class="text">
  <p>テキストテキストテキストテキストテキスト</p>
  <p>テキストテキストテキストテキストテキスト</p>
</div>
```

```css
.text > p:not(:first-child) {
  margin-top: 2em;
}
```

p要素それぞれにclassを振っているケースも見かけますが、「本文」のコンテナコンポーネント（`.text`）で囲むことで「本文内の段落スタイル」であることが明示的になります。

### テキストのスタイル

本文には「強調」「斜体」「上付き・下付き文字」などもよく登場します。適切なHTML要素を使用することを前提にスタイルを定義しておきましょう。

```html
<p><strong>太字による強調</strong>はstrong要素を使用します。</p>
<p><i>斜体</i>はi要素を使用します。</p>
<p>上付き文字<sup>※1</sup>はsup要素を使用します。</p>
<p>下付き文字（CO<sub>2</sub>）はsub要素を使用します。</p>
```

これらのスタイルをあらかじめ用意していなかった場合、必要になった時に実装のされ方にばらつきが出てしまう可能性があります。

```html:強調スタイルの実装のばらつき
<span class="bold">太字による強調</span>
...
<span style="font-weight: bold;">太字による強調</span>
```

### リストのスタイル

本文中には「普通の箇条書きリスト」もよく登場します。順序なしリスト（ul要素）と順序付きリスト（ol要素）のスタイルをあらかじめ用意しておくとよいでしょう。

箇条書きリストも、実装のされ方にばらつきが出やすい要素と言えます。

```html:セマンティックではない箇条書きリスト
<p>・テキストテキストテキスト<br>
・テキストテキストテキスト</p>

<p>1. テキストテキストテキスト<br>
2. テキストテキストテキスト</p>
```

### 「本文」コンポーネントの全体像

どのようなウェブサイトにおいても、ここに挙げた基本的なテキストスタイルはほぼ必要になります。このような「本文」のスタイルをしっかり用意しておくことで、サイト内のタイポグラフィの一貫性や妥当性は大きく向上します。

```html
<div class="text">
  <p>テキストテキストテキストテキストテキスト</p>
  <p>テキストテキストテキストテキストテキスト</p>
  <p><strong>太字による強調</strong>はstrong要素を使用します。</p>
  <p><i>斜体</i>はi要素を使用します。</p>
  <p>上付き文字<sup>※1</sup>はsup要素を使用します。</p>
  <p>下付き文字（CO<sub>2</sub>）はsub要素を使用します。</p>
  <ul>
    <li>箇条書きリスト</li>
    <li>箇条書きリスト</li>
  </ul>
  <ol>
    <li>箇条書きリスト</li>
    <li>箇条書きリスト</li>
  </ol>
</div>
```

```css
.text > p:not(:first-child),
.text > ul:not(:first-child),
.text > ol:not(:first-child) {
  margin-top: 2em;
}
```

上記のコード例では最低限のスタイルのみを指定しています。必要に応じてスタイルを追加してください。

## 2.3 見出し

続いて見出しの設計を考えます。見出しもウェブサイトのさまざまな箇所に頻繁に登場するコンポーネントであり、初期の設計が重要になります。

### 見出しのスタイル

見出しコンポーネントは原則としてh1〜h6要素を使用し、それぞれの階層を意識してスタイルを設計します。

サイト運用においては「デザイン上の見出しスタイル」とHTML要素が一致しないケースもあるため、見出しのスタイルはHTML要素に依存せずclassベースで管理する方法がよいでしょう。

```css
// NGというわけではないが
h2 {
  font-size: 2rem;
  line-height: 1.2;
}

// こちらのほうが汎用性が高い
.heading-2 {
  font-size: 2rem;
  line-height: 1.2;
}
```

```html
<h3 class="heading-2">HTMLとしてはh3だが、レベル2のスタイルを適用する見出し</h3>
```

### 見出しの拡張

必ずしもh要素だけで見出しが構成されるとは限らず、アイコン画像やテキストリンク、上付き文字や下付き文字が含まれる場合もあります。

複数のHTML要素がネストされる可能性があるため、見出しを `display: flex` などでスタイリングするときは注意が必要です。

```html
<h2 class="heading-2"><span>{何らかのアイコン}</span>見出しテキスト</h2>
...
<h3>弊社のCO<sub>2</sub>削減への取り組み</h3>
```

サイト規模や運用フローにもよりますが、あらかじめHTMLをラップし、拡張の余裕を持たせた構造にしておくことも検討するとよいでしょう。

```html
<!-- あらかじめdiv要素でラップしておく -->
<div class="header">
  <h2 class="heading-2">見出し</h2>
</div>
```

```html
<!-- 見出しの拡張に対応できる -->
<div class="header">
  <h2 class="heading-2">見出し</h2>
  <ul>
    <li><a href="#">見出しに付随するリンク</a></li>
  </ul>
</div>
```

# おわりに

font-sizeとline-heightは、ウェブタイポグラフィの基礎となる重要なプロパティです。これらを正しく理解し、丁寧に設計することが、高品質なタイポグラフィを実現する第一歩です。さまざまなCSSプロパティを複雑に駆使する前に、ブラウザのデフォルトスタイルを把握した上で小さく調整をしていくことが大切です。

具体的にタイポグラフィの設計を進める場合には、それぞれのコンポーネントに対して部分最適で個別に対応するのではなく、まず大きな基準を作り、バリエーションとして差分を作ることを意識するとよいでしょう。

タイポグラフィこそが最も重要なコンポーネント設計であると私は考えています。読みやすく、美しいウェブページを作るために、実装者として主体的にタイポグラフィに向き合っていきましょう。

# 参考

- [font-size - CSS: カスケーディングスタイルシート | MDN](https://developer.mozilla.org/ja/docs/Web/CSS/font-size)
- [line-height - CSS: カスケーディングスタイルシート | MDN](https://developer.mozilla.org/ja/docs/Web/CSS/line-height)
- [リチャード・ラター「ウェブタイポグラフィ─美しく効果的でレスポンシブな欧文タイポグラフィの設計」](https://wgn-obs.shop-pro.jp/?pid=152092905)