日本語・中国語・タイ語と text-wrap

単語間にスペースを使わない CJK・タイ語テキストで text-wrap: balance と pretty がどう振る舞うか。

Internationalization

詳細な説明

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: prettybalance は、英語のタイ語コンテンツに対しても、辞書由来の単語境界に基づいて同様に機能します。

lang 属性の設定

上記すべてが正しく機能するには、ドキュメントまたはブロックの言語を指定してください:

<html lang="ja">

または要素ごとに:

<p lang="zh">這是中文段落。</p>

lang がないと、ブラウザはデフォルトのセグメンタ(通常は英語スタイル)を使い、CJK では悪い結果が出ます。

ユースケース

CJK コンテンツを持つ国際化サイト、日本のEC、中国の技術ドキュメント、タイ語ニュースサイト、ランタイムで言語を切り替える多言語マーケティングページ、アジア向けアプリのダッシュボード。

試してみるCSS text-wrap プレイグラウンド

フルツールを開く