日本語の文章とline-heightに対する考察

# 行送り（line-height）の世界基準

アクセシビリティのスタンダードであるWCAG「達成基準 1.4.12: テキストの間隔を理解する」では、[~~行送りの最低値を1.5と定めている~~行送りを1.5にした場合でもデザインが破綻しないように促している](https://waic.jp/docs/WCAG21/#text-spacing)（@SaekiTominagaさんのご指摘で解釈を誤っていたことが発覚。修正いたします）。しかし世の中のホームページには、リセットCSSを変更していなかったり（あくまでブラウザ間の差異を無くすためのものであり、スタイルを後付けすることが推奨されているわけだが、~~そもそもどうしてアクセシビリティ基準を守らないんだろうか？[^1]~~　ただ、[sanitize.css](https://github.com/csstools/sanitize.css)など、line-heightがちゃんと1.5と設定されているリセットCSSもちゃんと存在する）、[古いBootstrap](https://stackoverflow.com/questions/19982651/why-does-bootstrap-set-the-line-height-property-to-1-428571429/20123813)をそのまま使っていたりして、line-heightが狭いのが割とある。そんな場合でも、[この達成基準を強引に満たすようにページを変更するブックマークレット](https://codepen.io/stevef/pen/YLMqbo)も存在する。

[^1]: とりあえずnormalize.cssのissuesに[この問題を起票してみた](https://github.com/necolas/normalize.css/issues/864)。しかし、「当該WCAG基準は最低値を規定しているものではない」と却下された。当時の自分はそれを理解できていなかった。

しかし、この行送りには罠がある。アルファベットを念頭に置いている（と推察される）からだ。こういう取り決めを作る人たちは欧米人が中心になるのは仕方がない。だが、そうではない言語を考えていかなければ真にアクセシブルとは言えない。特に仮名・漢字・ハングルといったCKJ文字は、アルファベットとは違う特性を持つ。

# アルファベットとCJK文字の違い

アルファベットは、大文字と小文字で構成される。ALL CAPS（こんな感じで全部大文字）でなければ、文字の大半は小文字である。つまり、aやeといった低めの文字や、g, yといった下にはみ出す文字が多数を占める。また、dやhのような上に突き出す小文字は重心が下の方にあるものが多い。

一方、CJK文字は型を押したように文字サイズが一定である。活版印刷がヨーロッパに先だって漢字圏で発達したというのは示唆的である。文字サイズがちぐはぐなアルファベットを印刷できるようにしたグーテンベルクの努力は想像に及ばぬものであったろう。

何が言いたいかというと、同じ文字サイズでもアルファベット(特に小文字)とCJK文字ではサイズ感が違ってくるということだ。CJK文字の方が全体的に大きくて、一種の威圧感がある。逆に、行送りの間隔はアルファベットの方が広く感じるように思う。

# 文字サイズの例：Noto SansおよびOpen Sansの場合

さて、実際の日本語とアルファベットのフォントサイズの差はどれくらいなのだろうか。可能な限り汎用的なフォントを選びたいとの理由で、ネット回線があればだれでも使えるNoto SansおよびOpen Sans（いずれも`font-size: 50px`）をサンプルとして用いることにした。
その結果がこちらである。

![スクリーンショット 2021-07-27 155532.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666342/926f80aa-69a9-32f2-8100-8b858fdb2876.png)

（「j」や「y」がline-heightからはみ出しているが、その分上部に隙間ができているので行が続いても重なることは無い。おそらく日本語との兼ね合いでbaselineが決定されているものと思われる。Mが大文字なのは、フォントサイズのemとMの関係性を確認したかったから。横幅が37pxなので、emとMのサイズはかなりの差がある。）
文字の高さに注目してみると、「た」が42px、「マ」が36px、「中」が46px、「T」が36px、「h」が38px、「x」が27pxという結果となった。日本語文の平均が40.25px、英文の平均が32.22857143pxである。ということは、日本語は大体アルファベットの1.25倍程度大きく表示されるということである。最頻値だと日本語42px、英文27px（いわゆる[エックスハイト](https://www.orikane.co.jp/glossary/6366/)）で、約1.56倍だ。この辺りはフォントによって当然変わってくるわけだが、大体のサイズ感は当たらずと言えども遠からずであろう。

従って、日本語の`line-height`は少なくとも`1.5×1.25 = 1.875`程度が必要だと考えられる。

# ルビ

しかし、これで終わらないのが日本語のややこしいところ。あまり使っているページを見かけないが、htmlには`<ruby>`や`<rt>`といった要素がある。
例としてはこんな感じ。<ruby>青眼の白龍<rt>ブルーアイズ・ホワイト・ドラゴン</rt></ruby>
これをhtmlで書くとこうなる。

```ルビ一例.html
<ruby>青眼の白龍<rt>ブルーアイズ・ホワイト・ドラゴン</rt></ruby>
```

chromeの`<rt>`要素の描画は特殊らしく、FirefoxのようにCSSの~~内部クラスを使っているわけでなく~~`display: ruby-text`を実装しておらず（説明が不適切なものだったので修正）、振る舞いがハードコーディングされているらしい。そのため、`line-height`や`margin-bottom`を設定しても`<rt>`の表示位置が変わらないので、`<ruby>`との行間を調整するには`transform: translateY(-**%)`とするしかない[^2]。`display: ruby-text`は内部の値（MDNによると「[複雑な内部構造があり、…その子要素や子孫要素が担う…役割があります。…「内部の」表示値として定義し、特定のレイアウトモードでのみ意味を持ちます。](https://developer.mozilla.org/ja/docs/Web/CSS/display#internal)」とのこと）のため、Firefoxの`<rt>`も位置調整ができない（公開後加筆）。

[^2]: この件はアクセシビリティ面で問題だと思われるので、monorailに[起票した](https://bugs.chromium.org/p/chromium/issues/detail?id=1233420)。機能の要望ということでUntriagedだが。

ただし、`<rt>`と上の行の間隔は調整できる。Chromeの場合`<rt>`（厳密には`<ruby>`内の`<rt>`）の文字サイズは`50%`。そのため、`<ruby>`を含む要素の`line-height`は`1 + 0.5 × 1.875 = 1.9375`ないといけない。`font-size`が`16px`ならline-heightが`31px`となる計算だ（良い子のみんな、`line-height`の値には単位を付けちゃいけないよ）。ただ、`<rt>`と`<ruby>`の行間を調整したなら、その分高さを考慮して計算しないといけない。`line-height`は奥が深い。

# `line-height`警察

Qiitaの場合、`line-height`の値は`1.9`なので、ほぼ合格である。
[Note](https://note.com/fladdict/n/n2b8d134901a3 "ルビのことを話題にしたのでこの記事にしました")は`p`要素の`line-height`が`36px`（倍率換算で`2`相当）。そのため十分なline-heightだが指定方法が良くないのが残念である。
[Yahoo! Japan](https://rdsig.yahoo.co.jp/mh/click/ytop/RV=1/RU=aHR0cHM6Ly93d3cueWFob28uY28uanAv)は`1.6`としっかりWCAG基準を満たしているが、気持ちせせこましい。
[朝日新聞](https://www.asahi.com/)は記事は`1.6`あるのだが、ベースの`line-height`が1.4なのは残念。デザイナーさんはWCAGを学んでほしい。
[読売新聞](https://www.yomiuri.co.jp/)はベースが`1.5`、本文が`1.7`と朝日よりも余裕のあるデザイン。
筆者の親会社である[サザビーリーグ](https://www.sazaby-league.co.jp/news/detail/20210721_afternoontealiving/)はベースが`1.7`、ニュース記事が`2em`と問題ない…ようで`em`を使っているのは減点。
筆者が勤めている[サザビーリーグHR](http://www.sazaby-league-hr.co.jp/)は`1.6`。やっぱりきついですね。

# あとがきに変えて

結論として、`line-height: 2`とするのがキリの良さと見やすさを両立できるのでベストだと言える。また、ルビがある場合の推奨高さも同じになるので一石二鳥だ。もう少し`line-height`を高くしてもいい。とにかく、世の中のホームページは行間が狭すぎるということが分かる。
どうかこの記事をWAICのメンバー様がご覧になりますように。そして、日本語の`line-height`議論が活発になりますように。

# 追記：最大`line-height`も考える

WCAGでは、"[Specifying line spacing in CSS](https://www.w3.org/WAI/WCAG21/Techniques/css/C21)"という文書もあり、そちらでは「行の高さが1.5～2倍あれば、前の行を読み終わった後に次の行に移るのが楽になる（Providing spacing between 1.5 to 2 allows them to start a new line more easily once they have finished the previous one.）」とある。つまり、それを超えると（アルファベット言語では）読みづらくなるということである。

これを今回の知見で得た日本語の行の高さの算出法に換算すると、アクセシビリティ的に最大の`line-height`はルビ無しで`2 × 1.25 = 2.5`、ルビありで`1 + 0.5 × 2.5 = 2.25`程度という計算になった。ルビが入ると高さが縮むというのも考え物なので、行の高さを広げたい場合は最大でも`2.25`にするというのが無難ではないか。この辺りも成熟した議論を待ちたい。

# 2022/01/28追記：達成基準のその他項目に関して

WCAG「達成基準 1.4.12: テキストの間隔を理解する」では、他にも以下の規定がある。

1. 段落に続く間隔をフォントサイズの少なくとも 2 倍に設定する
1. 文字の間隔 (字送り) をフォントサイズの少なくとも 0.12 倍に設定する
1. 単語の間隔をフォントサイズの少なくとも 0.16 倍に設定する

1番目はCJK言語の最適解は「１行分の字送りに設定する」だと思われる。これは言われなくてもたいていのホームページがそのような設定になっていることだろう。ただ、フォントサイズ基準の議論は少々的外れに感じる（個人の感想）。

2番目は`letter-spacing`を利用することになるが、CJK言語では満たすべきではないと考えられる。理由として、コンテキストによって読み方が変わってくるアルファベットとは違い、CJK言語は文字単位で考えるスタイル（一文字が意味を持つ漢字なんてその分かりやすい例）であること、本編で述べた通りCJK文字の組版が正方形で成り立っているため、スペーシングがあるとそれが崩れることが挙げられる。ハングルは表音文字なので、文字間隔を調整するメリットがあるかもしれない（自分が韓国語に関する知識を持ち合わせていないので、正確なことは分からない）。

3番目は、分かち書きがマストなハングルのみ考慮すべきである。日本語及び中国語では単語単位でスペースを入れて区切るのは特殊な記法であるが、日本語の場合分かち書きは全角スペースになるだろう。韓国（及び~~読んでいるとは思えないけど~~北朝鮮）のWebデザイナーさんは`word-spacing`の導入を検討していただきたい。

# 2022/03/04 修正内容

タイトルを「日本語でline-height:1.5って、ちょっときつくないですか？」から変更。
一部説明が不足していた個所を追記。