見出しを2行に折り返したときに、最後の行が1語だけになって間延びして見えることがあります。これを直すために <br> を手で入れたり、display: inline-block; で無理やり幅を調整したりした経験がある方も多いはずです。CSS の text-wrap を使うと、こうした改行位置の調整をブラウザーに任せられます。この記事では balance と pretty を中心に、5つの値の違い、使いどころ、日本語での効き方までを動かせるデモつきで解説します。
目次
見出しの最終行だけが1語になってしまう問題
ブラウザーがテキストを折り返すとき、標準の動作は「1行にできるだけ詰め込み、入らなくなったら次の行に送る」というものです。文章としてはこれで十分ですが、見出しやキャッチコピーのように文字が大きく行数が少ないところでは、最後の行に1語だけが取り残されることがあります。組版の世界で「泣き別れ」やオルファンと呼ばれる状態で、見た目のバランスが崩れ、読み手にも引っかかりを与えます。
従来この問題への対処は手作業でした。ちょうどいい位置に <br> を入れる、改行してほしくないかたまりを <span> で囲んで display: inline-block; にする、あるいは <wbr> で改行してもよい位置を教える、といった方法です。どれも効果はありますが、画面幅が変わると狙いが外れますし、あとから文言を差し替えるたびに調整し直すことになります。
text-wrap は、この「どこで折り返すか」の方針そのものを CSS で指定できるプロパティです。文字数や画面幅がどうであれ、ブラウザーがその方針に沿って折り返し位置を選び直してくれるので、マークアップを触らずに済みます。
text-wrap に指定できる値
指定できる値は5つです。wrap と nowrap は「折り返すかどうか」、balance / pretty / stable は「折り返すとして、どんな方針で位置を選ぶか」を決めます。
| 値 | 効果 |
|---|---|
wrap | 初期値。はみ出しが最小になるよう、これまでどおりの位置で折り返す |
nowrap | 折り返さない。行は改行されず、要素からはみ出す |
balance | 各行の長さがなるべく揃うように折り返し位置を選ぶ |
pretty | 速度より仕上がりを優先するアルゴリズムで折り返す。最終行が極端に短くなるのを抑える |
stable | ユーザーが編集しているとき、編集中の行より前の行の折り返しを動かさない |
balance / pretty / stable はいずれも「折り返しはする」という前提の値なので、wrap と同じように行は折り返されます。違うのは、どの位置を選ぶかというブラウザーの判断だけです。そのため、これらの値に対応していないブラウザーで見ても、レイアウトが壊れることはなく、ふつうの折り返しになるだけです。
balance で見出しの改行位置を揃える
いちばん出番が多いのが balance です。見出しに1行足すだけで、行の長さが揃うように折り返し位置が選び直されます。
/* 見出しの各行の長さを揃える */
h1,
h2,
h3 {
text-wrap: balance;
}
次のデモは、同じ見出しを text-wrap: wrap(初期値)と text-wrap: balance で並べたものです。折り返しが起きるように、あえて枠の幅を狭くしてあります。左は最後の行に少しだけ文字が残っているのに対し、右は2行の長さがほぼ同じになっているはずです。CSS タブの数値を書き換えて、枠の幅や文字サイズを変えたときの挙動も試してみてください。
<div class="compare">
<div class="box">
<p class="label">text-wrap: wrap(初期値)</p>
<h2 class="normal">text-wrap で見出しの改行位置を整える</h2>
<h2 class="normal">Balance the last line of a heading</h2>
</div>
<div class="box">
<p class="label">text-wrap: balance</p>
<h2 class="balanced">text-wrap で見出しの改行位置を整える</h2>
<h2 class="balanced">Balance the last line of a heading</h2>
</div>
</div>
body {
margin: 16px;
font-family: sans-serif;
color: #333;
}
.compare {
display: flex;
flex-wrap: wrap;
gap: 16px;
}
/* わざと幅を狭くして、見出しを折り返させる */
.box {
width: 250px;
padding: 12px 16px;
border: 1px solid #ddd;
border-radius: 6px;
}
.label {
margin: 0 0 8px;
color: #007bff;
font-size: 12px;
}
.box h2 {
margin: 0 0 16px;
font-size: 19px;
line-height: 1.6;
}
.box h2:last-child {
margin-bottom: 0;
}
/* 初期値。あふれが最小になる位置で折り返す */
.normal {
text-wrap: wrap;
}
/* 各行の長さが揃うように折り返し位置を選び直す */
.balanced {
text-wrap: balance;
}
ポイントは、この調整が要素の幅ではなく折り返し位置だけを変えていることです。見出しのボックス自体は親要素いっぱいに広がったままなので、背景色や下線を引いているデザインでも見た目が崩れません。display: inline-block; で幅を縮める昔ながらの方法とは、ここが大きく違います。
カードや一覧のタイトルに使う
記事一覧のカードのように、幅が狭く文字数がまちまちなタイトルが並ぶ場所も balance の得意分野です。カードごとにタイトルの長さが違うと、あるカードだけ最後の行が短く尻すぼみに見えてしまいますが、balance を当てておけばどのカードもきれいに収まります。
次のデモではチェックボックスで切り替えられるようにしました。チェックを入れると .card h3 に text-wrap: balance; が適用されます。ブラウザーの幅を変えながら切り替えると、どの幅でも行が揃い直すことが分かります。
<label class="switch">
<input type="checkbox" id="toggle">
カードのタイトルに text-wrap: balance を適用する
</label>
<div class="cards">
<article class="card">
<h3>CSS カスタムプロパティで配色をまとめて管理する</h3>
<p>2026.08.16</p>
</article>
<article class="card">
<h3>Flexbox の gap プロパティ</h3>
<p>2026.08.10</p>
</article>
<article class="card">
<h3>画像の遅延読み込みで表示速度を改善する方法</h3>
<p>2026.08.02</p>
</article>
</div>
body {
margin: 16px;
font-family: sans-serif;
color: #333;
}
.switch {
display: inline-block;
margin-bottom: 16px;
font-size: 13px;
cursor: pointer;
}
.cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
gap: 12px;
}
.card {
padding: 12px 16px;
border: 1px solid #ddd;
border-radius: 6px;
}
.card h3 {
margin: 0 0 8px;
font-size: 16px;
line-height: 1.6;
}
.card p {
margin: 0;
color: #888;
font-size: 12px;
}
/* チェックを入れたときだけタイトルの行を均等にする */
body:has(#toggle:checked) .card h3 {
text-wrap: balance;
}
グリッドの列数が変わってカードの幅が変化しても、こちらで数値を調整する必要はありません。文言を差し替えたときも同じです。手作業の <br> は入稿のたびに見直しが必要でしたが、balance なら CSS に1行書いておくだけで済みます。
本文には pretty、入力欄には stable
balance は行の長さを揃えるために全体を計算し直すので、ブラウザーが扱える行数に上限があります(詳しくは後述します)。本文のような長いテキストには効かない設計なので、そこで使うのが pretty です。pretty は行の長さを均等にするのではなく、速度より仕上がりを優先するアルゴリズムで折り返し位置を選び、最終行に1語だけが取り残されるような結果を避けようとします。
/* 見出しは行の長さを揃える */
h1,
h2,
h3 {
text-wrap: balance;
}
/* 本文は仕上がり優先で折り返す */
p,
li {
text-wrap: pretty;
}
/* 入力中に前の行が動かないようにする */
[contenteditable],
textarea {
text-wrap: stable;
}
次のデモは、同じ英文を wrap と pretty で並べたものです。pretty の側では最終行が1語だけにならないよう、その手前の行から文字が送られます。ただし pretty がどこまで手を入れるかはブラウザーの実装によって差があり、テキストや幅によっては見た目が変わらないこともあります。
<div class="compare">
<div class="box">
<p class="label">text-wrap: wrap(初期値)</p>
<p class="body normal">A paragraph looks unbalanced when the browser pushes only the very last short word of the sentence down onto its own line.</p>
</div>
<div class="box">
<p class="label">text-wrap: pretty</p>
<p class="body pretty">A paragraph looks unbalanced when the browser pushes only the very last short word of the sentence down onto its own line.</p>
</div>
</div>
body {
margin: 16px;
font-family: sans-serif;
color: #333;
}
.compare {
display: flex;
flex-wrap: wrap;
gap: 16px;
}
.box {
width: 250px;
padding: 12px 16px;
border: 1px solid #ddd;
border-radius: 6px;
}
.label {
margin: 0 0 8px;
color: #007bff;
font-size: 12px;
}
.body {
margin: 0;
font-size: 14px;
line-height: 1.8;
}
.normal {
text-wrap: wrap;
}
/* 最終行が極端に短くならないように折り返しを調整する */
.pretty {
text-wrap: pretty;
}
stable は見た目を整えるための値ではありません。contenteditable の領域などで文字を入力していると、途中に文字を足すたびに前後の行がまとめて組み直され、いま打っている位置が上下に動いてしまうことがあります。stable を指定すると、編集している行より前の行はそのまま固定されるので、入力中の視線が安定します。編集画面やコメント欄のようなインターフェイス向けの値だと考えてください。
なお pretty は名前のとおり時間をかけて折り返しを検討する値なので、記事全体のように長いテキストへ無条件に適用するとレンダリングのコストが増えます。MDN でも長いテキストブロックへの使用は避けるべきだと注意されています。まずは本文の中でも目立つ導入文やリード文など、範囲を絞って当てるのが無難です。
text-wrap は2つのプロパティのショートハンド
先ほど「値は2種類の役割に分かれる」と書きましたが、これは仕様のうえでも別々のプロパティになっています。text-wrap は次の2つをまとめて指定するショートハンドです。
| プロパティ | 指定できる値 |
|---|---|
text-wrap-mode | wrap / nowrap。そもそも折り返すかどうか |
text-wrap-style | auto / balance / pretty / stable。どんな方針で折り返すか |
つまり text-wrap: balance; は、text-wrap-mode: wrap; と text-wrap-style: balance; を同時に書いたのと同じ意味になります。text-wrap-style の初期値である auto は、text-wrap のキーワードとしては wrap に含まれている形です。
/* この2つは同じ意味 */
.title {
text-wrap: balance;
}
.title {
text-wrap-mode: wrap;
text-wrap-style: balance;
}
個別のプロパティを使う利点は、片方だけを上書きできることです。たとえば折り返しの方針は親から継承したまま、ある要素だけ折り返しを止めたいなら text-wrap-mode: nowrap; と書けば、text-wrap-style の指定は影響を受けません。ショートハンドの text-wrap: nowrap; を使うと、書かなかった text-wrap-style は初期値の auto に戻ります。
日本語のテキストではどう効くか
ここは押さえておきたいところです。英語は単語のあいだに空白があり、折り返せる位置がその空白に限られます。だからこそ「最後の単語だけが次の行に落ちる」という現象が起きやすく、balance や pretty の効果もはっきり見えます。
一方、日本語には単語の区切りとなる空白がありません。禁則処理が許す範囲であれば、ほとんどどの文字と文字のあいだでも改行できます。結果として行の末尾は自然と端まで埋まり、行の長さはもともとほぼ揃っています。そのため balance を指定しても変化がわずかだったり、まったく見た目が変わらなかったりすることがあります。
とはいえ効果がないわけではありません。短い見出しで最終行が1〜2文字だけになるような場合や、日本語のなかに英単語・カタカナ語・数字が混じっていて、そのかたまりが行をまたげずに大きな余白を作っている場合には、balance がはっきり効きます。前掲の最初のデモでも、日本語の見出しの2行の長さが揃っているのが確認できます。
「行の長さ」ではなく「意味のかたまりで改行したい」という日本語特有の要望は、text-wrap の担当ではありません。対応しているブラウザーでは word-break: auto-phrase; が文節を意識した改行位置を選んでくれますし、対応状況が気になる場合は BudouX のようなライブラリで改行位置を事前に埋め込む方法もあります。目的が違うので、balance と併用しても構いません。
word-break や overflow-wrap とは役割が違う
折り返しに関わる CSS プロパティは他にもあるため、混同しないように整理しておきます。ポイントは、「どこで改行してよいか」を決めるプロパティと、「改行してよい位置のなかからどこを選ぶか」を決めるプロパティが別だということです。text-wrap は後者にあたります。
| プロパティ | 役割 |
|---|---|
word-break | 単語の途中で改行してよいかなど、改行できる位置のルールを変える |
overflow-wrap | ふつうに折り返すとはみ出す長い文字列に限り、途中での改行を許可する |
line-break | 日本語などの禁則処理の厳しさを切り替える |
text-wrap | 改行できる位置のなかから、どこを選ぶかの方針を決める |
長い URL がカードからはみ出す、といった問題は overflow-wrap: anywhere; の担当であって、text-wrap: balance; では解決しません。逆に、はみ出してはいないが最終行が寂しい、という見た目の問題に word-break を使うと、単語が途中で切れて読みにくくなります。症状に応じて使い分けてください。
思ったとおりの位置で改行されないとき
text-wrap: balance; を書いたのに何も変わらない、というときは次の順に確認すると原因が絞れます。
ブラウザーが値に対応していない
balance / pretty / stable は同時に実装されたわけではなく、ブラウザーごとに対応時期が異なります。未対応の値は単に無視され、通常の折り返しになるだけなので、レイアウトが壊れる心配はありません。逆に言うと「効かない=壊れていない」ため、対応していないことに気づきにくい値でもあります。使う前に MDN のブラウザー互換性表で確認しておきましょう。値の有無で処理を分けたい場合は、次のように @supports が使えます。
/* 対応していないブラウザー向けのフォールバック */
.hero__title {
max-width: 20em; /* 幅を絞って行数を抑える */
}
/* balance が使えるなら幅の制限は不要 */
@supports (text-wrap: balance) {
.hero__title {
max-width: none;
text-wrap: balance;
}
}
行数がブラウザーの上限を超えている
balance は行の長さを揃えるために、テキスト全体を何通りにも折り返し直して比べる必要があります。処理の負荷が高いため、ブラウザーは balance を適用する行数に上限を設けています。上限は実装によって異なりますが、いずれも数行程度で、それを超えるブロックでは balance は無視されて通常の折り返しになります。
デスクトップでは2行に収まっていた見出しが、スマートフォンの幅では5行、6行と増えて上限を超え、そこだけ効かなくなる、というのはよくあるパターンです。balance は見出し・キャッチコピー・引用・図版のキャプションなど、もともと数行で収まるものに使う値だと割り切りましょう。本文全体に指定するのは、効かないだけでなく意図とも合いません。長い文章には pretty を検討してください。
white-space: nowrap と打ち消し合っている
white-space は white-space-collapse と text-wrap-mode のショートハンドです。つまり white-space: nowrap; と書くと text-wrap-mode: nowrap; が設定され、折り返しそのものが起きなくなります。折り返しが起きなければ、balance が選ぶべき折り返し位置も存在しません。
やっかいなのは、この2つはどちらもショートハンドなので書いた順番で結果が変わることです。text-wrap: balance; のあとに white-space: nowrap; を書けば折り返しは止まり、逆順なら text-wrap 側が text-wrap-mode を wrap に戻します。リセット CSS やコンポーネントの共通スタイルで white-space が指定されていないか、開発者ツールで確認してみてください。片方だけを狙って上書きしたいときは、ショートハンドではなく text-wrap-style や text-wrap-mode を直接書くのが確実です。
text-align: justify と組み合わせている
両端揃え(text-align: justify;)は、最終行を除くすべての行を文字間や単語間の調整で同じ幅まで引き伸ばします。行の見た目の長さがもともと揃ってしまうため、balance が折り返し位置を変えても差として現れるのは最終行の長さと単語間のアキくらいで、期待したほどの変化を感じられないことが多くなります。両端揃えのデザインで最終行の見え方を整えたい場合は、balance に頼りきらず、実際の表示を見ながら判断してください。
昔入れた br タグが残っている
text-wrap が調整するのは、あくまでブラウザーが自動で折り返す位置です。<br> による強制改行はそれより優先されるので、以前の調整用に入れた <br> が残っていると、そこで必ず改行され、balance の効果が打ち消されて見えます。text-wrap: balance; に切り替えるときは、テンプレートや投稿本文に残っている手動の改行を先に外しておきましょう。
まとめ
text-wrap は、テキストをどんな方針で折り返すかを指定するプロパティで、text-wrap-mode と text-wrap-style のショートハンドです。行の長さを揃える balance は見出しやキャッチコピーなど数行のテキスト向けで、ブラウザーが扱える行数に上限があるため本文には使いません。本文には最終行が短くなりすぎるのを抑える pretty、入力中の再レイアウトを抑えたい場所には stable を使います。日本語ではどこでも改行できるぶん効果が控えめになりますが、短い見出しや英数字が混じる文言では十分に役立ちます。word-break や overflow-wrap は「どこで改行してよいか」を決める別の役割のプロパティなので、症状に応じて使い分けてください。