日本語・中国語・タイ語と text-wrap
単語間にスペースを使わない CJK・タイ語テキストで text-wrap: balance と pretty がどう振る舞うか。
詳細な説明
CJK の折り返しが特殊な理由
英語の行分割アルゴリズムは 単語境界 (スペース)で動作します。日本語、中国語、タイ語は単語間にスペースを使いません。代わりに:
- 日本語 はほとんどの文字(かな・漢字)の間で改行可能ですが、行頭禁則・行末禁則(
kinsoku shori)のように特定の組み合わせを禁止するルールがあります。 - 中国語 は任意の漢字2文字間で改行可能で、句読点ルールが適用されます。
- タイ語 は単語境界を辞書またはルールベースのセグメンタで見つける必要があります(これが難しい)。
ブラウザは CJK の text-wrap をどう扱うか
日本語と中国語については、ブラウザは行分割の機会空間がはるかに密だと扱います(禁則を考慮した上で、ほぼすべての文字間が改行候補)。text-wrap: balance は検討すべき改行候補が大幅に増えるため、アルゴリズムは引き続き機能しますが、結果として得られるバランスは細かい粒度のものになります。
text-wrap: pretty は CJK では効果が薄めです。「行末の単発単語を防ぐ」というオーファン回避の概念が、文字単位の改行に直接当てはまらないためです。
実用的な推奨
日本語・中国語の見出し:
h1[lang="ja"], h1[lang="zh"] {
text-wrap: balance;
/* CJK は line-height を詰めた方が見栄えが良い */
line-height: 1.4;
}
日本語・中国語の本文:
article[lang="ja"] p, article[lang="zh"] p {
/* pretty の効果は限定的; デフォルト折り返しで十分 */
text-wrap: wrap;
line-height: 1.7; /* CJK は呼吸が必要 */
}
CJK の単語内での改行を抑制したい場合は word-break: keep-all を使います(連なりを単位として扱う):
.no-cjk-break {
word-break: keep-all;
overflow-wrap: anywhere;
}
スクリプト混在テキスト
英語と日本語が混在するテキスト("React の useState は便利")の場合、ブラウザは各スクリプトセグメントに自動的に異なるルールを適用します。balance も pretty も機能しますが、2つのスクリプトの改行候補密度が違うため、わずかな非対称が見られることがあります。
タイ語
タイ語は改行位置を見つけるために単語セグメンテーションが必要です。モダンブラウザはタイ語辞書を内蔵し正しくセグメントします。text-wrap: pretty と balance は、英語のタイ語コンテンツに対しても、辞書由来の単語境界に基づいて同様に機能します。
lang 属性の設定
上記すべてが正しく機能するには、ドキュメントまたはブロックの言語を指定してください:
<html lang="ja">
または要素ごとに:
<p lang="zh">這是中文段落。</p>
lang がないと、ブラウザはデフォルトのセグメンタ(通常は英語スタイル)を使い、CJK では悪い結果が出ます。
ユースケース
CJK コンテンツを持つ国際化サイト、日本のEC、中国の技術ドキュメント、タイ語ニュースサイト、ランタイムで言語を切り替える多言語マーケティングページ、アジア向けアプリのダッシュボード。