CSSのtext-wrap: balanceで見出しの折り返しを整える
見出しに text-wrap: balance を1行足すと、ブラウザーが各行の長さがそろうように折り返し位置を選び直します。最後の行に「を防ぐ」だけが残るような見出しが、同じ行数のまま、長さのそろった行になります。日本語の見出しでは単語の途中で折り返しやすくなるので、Chrome と Edge なら word-break: auto-phrase もいっしょに付けると、文節の切れ目で折り返せます。
検証環境は Ubuntu 24.04、Node.js 22.23.4、Playwright 1.63.0、Chromium 153 です。フォントは Noto Sans CJK JP を入れ、幅 360px、文字の大きさ 28px の h1 を Playwright で開いて、1文字ずつの位置から行ごとの文字列と幅を測りました。Firefox と Safari での表示、縦書きは試していません。各ブラウザーの対応バージョンは、互換性データ(@mdn/browser-compat-data 8.1.8)の値です。
text-wrap: balance を見出しに付ける
書き方は、見出しの要素に1行足すだけです。
h1,
h2 {
text-wrap: balance;
}
検証環境で、「日本語の見出しがスマホで変な位置で折り返されるのを防ぐ」という見出しを幅 360px に入れ、指定なしと balance を比べました。
| 行 | 指定なし | text-wrap: balance |
|---|---|---|
| 1行目 | 日本語の見出しがスマホで(335.2px) | 日本語の見出しがス(252px) |
| 2行目 | 変な位置で折り返されるの(336px) | マホで変な位置で折(252px) |
| 3行目 | を防ぐ(84px) | り返されるのを防ぐ(252px) |
指定なしでは、1行目と2行目に入るだけ詰め込み、3行目は「を防ぐ」の3文字だけになりました。balance では3行とも9文字、252px にそろいました。どちらも3行で、要素の高さも変わりません。CSS の仕様でも、balance は各行の余白がそろうように折り返し位置を選ぶ値で、5行以下なら行数を変えてはいけないと定められています。
英語の見出し「How to balance the line breaks of a heading with CSS」でも、指定なしでは3行目が「CSS」だけになり、balance では「How to balance」「the line breaks of a」「heading with CSS」の3行に分かれました。英語は単語の切れ目で折り返すので、行の長さが少しばらつきます。
1行に収まる見出しでは、balance を付けても何も変わりませんでした。サイトの見出しにまとめて付けておいても、短い見出しには影響しません。
日本語は word-break: auto-phrase と組み合わせる
上の表のとおり、balance だけでは「ス/マホ」「折/り返される」のように、単語の途中で折り返しました。長さをそろえることだけを優先するので、こうなります。
Chrome と Edge では、word-break: auto-phrase を足すと、文節の切れ目でだけ折り返すようになります。MDN では、言語ごとの分析をして、自然なフレーズの途中で改行しないようにする値と説明されています。
h1,
h2 {
text-wrap: balance;
word-break: auto-phrase;
}

両方を付けると、「日本語の見出しが」「スマホで変な位置で」「折り返されるのを防ぐ」の3行になりました。行の幅は 224px、251.2px、280px で、balance だけのときほどぴったりはそろいません。そのかわり、どの行も文節の切れ目で終わっています。
word-break: auto-phrase だけを付けると、「日本語の見出しがスマホで」「変な位置で」「折り返されるのを防ぐ」となり、2行目が短く残りました。文節で区切る指定と、長さをそろえる指定は別のものなので、両方を付けたときにいちばん読みやすくなりました。
検証環境で、同じ見出しの要素に lang="en" を付けると、balance だけのときと同じ「ス/マホ」の折り返しに戻りました。auto-phrase を効かせるには、要素の言語が日本語(lang="ja")になっている必要があります。
要素の幅は縮まない
balance で変わるのは、行の中の文字の並びだけです。要素の幅は変わりません。検証環境では、balance を付けても h1 の幅は 360px のままでした。width: fit-content と max-width: 360px を指定しても、幅は 360px のままです。
上の画像の点線の枠のとおり、文字の右側に空きが残ります。画像では見出しに薄い水色の背景を付けていて、その空きにも色が付いています。text-align: center で中央寄せにしても、折り返し位置は左寄せのときと同じでした。
br で改行した見出しは、後ろの部分が整わなかった
見出しの途中に <br> を入れて、意図的に改行することがあります。<br> のあとの部分は、balance を付けても整いませんでした。
「猫の手も借りたいときに」のあとに <br> を入れ、続けて上と同じ見出しを入れると、<br> のあとは「日本語の見出しがスマホで」「変な位置で折り返されるの」「を防ぐ」となり、指定なしと同じ折り返しのままでした。仕様では、強制改行で区切られた行のまとまりは、それぞれ別に整えると定められています。仕様どおりなら <br> のあとも整いますが、検証環境の Chromium 153 ではそうなりませんでした。
行ごとに display: block の span で包むと、後ろの部分も整いました。
<h1>
<span>猫の手も借りたいときに</span>
<span>日本語の見出しがスマホで変な位置で折り返されるのを防ぐ</span>
</h1>
h1 {
text-wrap: balance;
}
h1 span {
display: block;
}

text-wrap は子要素に継承されるので、span に同じ指定を書き直す必要はありません。検証環境でも、body に text-wrap: balance を書くと、中の h1 の計算値が balance になり、長さのそろった3行で表示されました。
7行以上になると、Chromium では整わない
balance は、長い文章には効きません。MDN の text-wrap-style のページには、行数の多い文章では計算の負荷が高いため、Chromium では6行以下、Firefox では10行以下のときにだけ働くと書かれています。
検証環境で、1行に12文字入る幅の要素に、文字数を変えた文章を入れて試しました。
| 指定なしでの行数 | balance を付けたとき |
|---|---|
| 2行 | 7文字ずつにそろう |
| 4行 | 10・10・9・9文字にそろう |
| 6行 | 11・11・10・10・10・10文字にそろう |
| 7行 | 指定なしと同じ(最後の行は2文字) |
| 10行 | 指定なしと同じ(最後の行は2文字) |
6行まではそろい、7行になると指定なしと同じ折り返しに戻りました。見出しや図のキャプションのような短い文章に付けるもの、と考えておくと迷いません。MDN でも、見出し、キャプション、引用のような数行の文章に向く値とされています。長い段落には、速さより見た目を優先して折り返す text-wrap: pretty という別の値があります。
text-wrap と text-wrap-style のどちらで書くか
text-wrap は、折り返すかどうかを決める text-wrap-mode と、どう折り返すかを決める text-wrap-style をまとめて指定する一括指定プロパティです。text-wrap: balance と書くと、text-wrap-mode は wrap、text-wrap-style は balance になりました。text-wrap-style: balance だけを書いても、同じ折り返しになりました。
互換性データでは、対応しているバージョンが次のように違います。
| ブラウザー | text-wrap: balance | text-wrap-style: balance | word-break: auto-phrase |
|---|---|---|---|
| Chrome・Edge | 114 | 130 | 119 |
| Firefox | 121 | 124 | 対応なし |
| Safari(iOS を含む) | 17.5 | 17.5 | 対応なし(Technology Preview のみ) |
Chrome・Edge と Firefox では、一括指定の text-wrap: balance のほうが古いバージョンから対応しています(Safari はどちらも 17.5)。word-break: auto-phrase は互換性データで実験的な機能とされていて、Chrome と Edge だけが対応しています。Firefox と Safari では auto-phrase の指定は効かず、balance だけが効きます。
white-space は text-wrap-mode もいっしょに決める一括指定なので、あとから書くと、折り返すかどうかの指定(text-wrap-mode)が上書きされます。検証環境で、text-wrap: balance のあとに white-space: nowrap を書くと、text-wrap-mode が nowrap になり、見出しは折り返さずに1行のまま、幅 755.2px まで要素の外にはみ出しました。white-space: normal のときは、balance のまま3行に整いました。





