メインコンテンツまでスキップ
  • Created:
  • Updated:
  • Author:
    Takeshi Takatsudo

text-wrap: balanceとpretty

問題

見出しや短いテキストブロックは、最終行に1つの単語だけが取り残される(オーファン)ような、不自然な行分割になることがよくあります。開発者は従来、手動の&nbsp;文字、明示的な<br>タグ、またはテキスト幅を計測してリフローするJavaScriptベースの対策で回避してきました。これらのアプローチは脆弱で、ビューポートサイズ、フォントサイズ、言語が異なると壊れます。現在ではCSSがtext-wrapプロパティでこの問題をネイティブに処理します。

解決方法

text-wrapプロパティは、デフォルトのwrapに加えて、テキストの改行を細かく制御する3つの値を提供します:

  • balance — テキストをすべての行に均等に分配し、特定の行だけが極端に長かったり短かったりしないようにします。見出し、ラベル、短いテキストブロックに最適です。
  • pretty — 段落の最終行にオーファン(孤立した単語)が残るのを防ぎます。ブラウザが前の行の改行位置を調整して、最終行に少なくとも2つの単語が残るようにします。本文テキスト向けに設計されています。
  • stable — 編集可能なコンテンツが変更された際に、すでにレイアウトされた行が再折り返しされないようにします。contenteditable領域やライブ編集インターフェースに便利です。

基本原則

見出しや短いテキストにはbalanceを使う

text-wrap: balanceは、すべての行をほぼ同じ幅にすることで動作します。ブラウザが最適な改行位置を計算し、最も短い行ができるだけ長くなるようにします。これにより、見出し、プルクオート、キャプションに最適な、視覚的に中央寄りで均等なテキストブロックが作られます。

ただし、パフォーマンス上の理由から、ブラウザはバランシングを約6行までに制限しています。そのしきい値を超えると、テキストは通常の折り返しにフォールバックします。

本文テキストにはprettyを使う

text-wrap: prettyは最終行に特化しています。前の行の改行位置を調整して、最終行に1つの単語だけが残ることを防ぎます。balanceとは異なり、すべての行を均等にしようとはせず、末尾がきれいに見えることだけを保証します。

編集可能なコンテンツにはstableを使う

text-wrap: stableは、新しいコンテンツがその後に入力された際に、以前レイアウトされた行がシフトするのを防ぎます。これにより、contenteditable要素やテキストエディタでの不快な再折り返し効果を回避できます。

コード例

基本的な使い方

h1,
h2,
h3 {
text-wrap: balance;
}

p {
text-wrap: pretty;
}

本番タイポグラフィシステム

/* すべての見出しレベルをバランス */
h1,
h2,
h3,
h4,
h5,
h6 {
text-wrap: balance;
}

/* 本文テキストのオーファンを防止 */
p,
li,
blockquote {
text-wrap: pretty;
}

/* 編集可能な領域にstableラッピング */
[contenteditable] {
text-wrap: stable;
}
balance vs バランスなし — 見出しの比較
本文テキストのpretty — オーファン防止
balanceの行数制限 — 短いテキスト vs 長いテキスト
実践的なタイポグラフィシステム — 見出し + 本文テキスト
プログレッシブエンハンスメント — グレースフルデグラデーション

CJKと日本語テキストにおける注意点

text-wrap: balancetext-wrap: prettyはアルファベット言語を前提に設計されており、日本語や他のCJK(中国語・日本語・韓国語)テキストには予期しない動作をします。見出しや段落にこれらのプロパティをグローバルに適用すると、日本語テキストが不自然な位置で改行され、右側に大きな余白が生じることがよくあります。

なぜ崩れるのか

アルファベット言語では、ブラウザはスペースや句読点を使って改行位置を分散させる際の単語境界を識別します。日本語には単語間のスペースがなく、すべての文字位置が有効な改行ポイントになります。text-wrap: balanceが行の長さを均等にしようとする際、自然な文節の途中で任意の文字位置に改行が入ってしまいます。その結果、見出しの最初の行が文節の途中で終わり、右側に目立つ大きな空白が生じます。

text-wrap: balance — 英語はうまく動作、日本語は崩れる

日本語でbalanceを適用したバージョンは、ブラウザが日本語の単語境界を認識しないため、「の」や「な」などの助詞の後など不自然な位置で改行されることがよくあります。改行が恣意的に感じられ、最初の行の右余白が目立つほど大きくなります。

word-break: auto-phraseによる回避策

Chrome 119+ではword-break: auto-phraseが導入されました。これはBudouXという機械学習エンジンを使って日本語テキストの自然な文節境界を識別します。text-wrap: balanceと組み合わせると、ブラウザは任意の文字位置ではなく、その文節境界を基準にバランシングを行います。

h1,
h2,
h3 {
text-wrap: balance;
word-break: auto-phrase; /* Chrome 119+ — 日本語の改行を改善 */
}
word-break: auto-phrase — 日本語の文節を考慮したバランシング(Chrome 119+)

word-break: auto-phraseが日本語の文節検出を有効にするには、要素または親要素にlang="ja"が必要です。lang属性がないとこのプロパティは効果を持ちません。FirefoxはまだAuto-phraseをサポートしていません。Safariのサポートも限定的です。利用前に現在のブラウザ互換性を確認してください。

ロケールスコープのフォールバックパターン

日本語または多言語サイトでは、lang属性セレクターを使って日本語コンテンツのtext-wrapをリセットするのが最も安全なアプローチです:

/* グローバルにbalanceを適用 */
h1,
h2,
h3 {
text-wrap: balance;
word-break: auto-phrase; /* Chromeで効果あり */
}

/* auto-phraseのサポートなしにbalanceが崩れる日本語向けにリセット */
[lang="ja"] :is(h1, h2, h3) {
text-wrap: initial;
}

/* auto-phraseをサポートするChromeでbalanceを再有効化 */
@supports (word-break: auto-phrase) {
[lang="ja"] :is(h1, h2, h3) {
text-wrap: balance;
}
}
ロケールスコープパターン — 日本語はリセット、英語はbalance

まとめ

プロパティ英語日本語
text-wrap: balanceうまく動作する任意の文字位置で改行される
text-wrap: prettyうまく動作するほぼ無害だが、オーファンの概念がCJKにはあまり当てはまらない
word-break: auto-phrase効果なし文節を考慮した改行を改善する(Chrome 119+のみ)

推奨: 日本語や多言語プロジェクトでは、見出しにtext-wrap: balanceを無条件に適用しないようにしましょう。日本語コンテンツでは省略するか、上記のロケールスコープの@supportsパターンを使うか、またはChromeでのみ改善が見られることを受け入れるかのいずれかを選択してください。

ブラウザサポート

  • text-wrap: balance — Chrome 114+、Edge 114+、Firefox 121+、Safari 17.5+でサポートされています。2025年時点で広くサポートされています。
  • text-wrap: pretty — Chrome 117+、Edge 117+、Safari 17.4+でサポートされています。Firefoxは2026年初頭時点でまだ対応待ちです。
  • text-wrap: stable — Chrome 120+、Edge 120+、Firefox 121+でサポートされています。Safariは対応待ちです。

3つの値すべてがグレースフルにデグレードします — 未対応のブラウザはデフォルトのtext-wrap: wrap動作を使用するだけなので、今すぐ適用してもリスクはありません。

AIがよくやるミス

  • text-wrap: balanceを長い本文の段落に適用する — 約6行以下のブロックでのみ動作し、適用されたとしても不自然に狭いテキストブロックになる
  • text-wrap: balanceがネイティブに解決する問題を、JavaScriptで行分割を計算して<br>タグを挿入する方法で対処する
  • オーファンを防ぐために最後の2つの単語の間に&nbsp;を挿入する — ビューポート幅が変わると壊れる脆弱な方法。代わりにtext-wrap: prettyを使いましょう
  • text-wrap: balancetext-align: centerを混同する — balanceは行の長さを均等にするために改行位置を調整するもので、配置を変更するものではない
  • 見出し要素にデフォルトでtext-wrap: balanceを設定しない — すべての見出しレベルのベースラインスタイルとして設定すべき
  • ナビゲーション項目やバッジなど、特定の幅が必要な要素にtext-wrap: balanceを適用する — balanceは要素の固有の幅を予期しない形で変更する可能性がある

使い分け

text-wrap: balance

  • 見出し(h1h6
  • プルクオートやblockquoteテキスト
  • キャプションやfigcaption
  • カードタイトルやヒーローテキスト
  • 視覚的な対称性が重要な短いテキストブロック(6行以下)

text-wrap: pretty

  • 本文の段落
  • 折り返しのあるリスト項目
  • 説明文やサマリー
  • 最終行に1つの単語だけが残るのを避けたい長文テキスト

text-wrap: stable

  • contenteditable要素
  • ライブテキストエディタや入力エリア
  • チャットメッセージの作成フィールド
  • テキストが活発に編集されており、再折り返しが妨げになるコンテキスト

参考リンク