CSS の text-wrap: balance でテキストの行末バランスを自動調整する

見出しやカードのタイトルなど、短めのテキストブロックで最終行だけ極端に短くなってしまうことがあります。たとえば 3 行の見出しで、最後の行に 1 文字だけ残るような状態です。これまではデザイナーが手動で改行を入れたり、JavaScript で文字数を計算して調整したりしていましたが、CSS の text-wrap: balance を使えばブラウザが自動的に各行の長さを均等に近づけてくれます。

text-wrap プロパティの概要

text-wrap はテキストの折り返し方法を制御するプロパティです。従来のブラウザは行末まで詰めてから次の行に送る auto(デフォルト)の挙動しかありませんでしたが、CSS Text Module Level 4 で新しい値が追加されました。

説明
auto従来どおりの折り返し
balance各行の幅をできるだけ均等にする
pretty孤立語(widow)を避ける
stable編集中にレイアウトが動かない
nowrap折り返さない

このうち balance は各行のテキスト幅を均等に分配し、pretty は最終行が極端に短くならないよう調整します。prettybalance ほど積極的に行幅を揃えず、最終行の孤立だけを防ぐイメージです。

基本的な使い方

指定は非常にシンプルで、対象の要素に text-wrap: balance を書くだけです。

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

実際にどう変わるか、デモで確認できます。

HTML
CSS
JavaScript
<div class="demo-container">
    <div class="card">
        <h3 class="no-balance">CSSのtext-wrap: balanceでテキストの行末バランスを自動調整する方法</h3>
        <p class="label">text-wrap: auto(デフォルト)</p>
    </div>
    <div class="card">
        <h3 class="with-balance">CSSのtext-wrap: balanceでテキストの行末バランスを自動調整する方法</h3>
        <p class="label">text-wrap: balance</p>
    </div>
</div>
.demo-container {
    display: flex;
    gap: 20px;
    max-width: 600px;
}
.card {
    flex: 1;
    padding: 16px;
    border: 1px solid #ddd;
    border-radius: 8px;
    background: #fafafa;
}
.card h3 {
    font-size: 16px;
    line-height: 1.6;
    margin: 0 0 8px 0;
}
.no-balance {
    text-wrap: auto;
}
.with-balance {
    text-wrap: balance;
}
.label {
    font-size: 12px;
    color: #888;
    margin: 0;
}

balance を指定した側は最終行だけが極端に短くなる現象が解消され、各行がほぼ同じ幅に収まっています。

行数制限がある

text-wrap: balance にはブラウザ側のパフォーマンス制約があり、Chrome では 6 行以内のテキストブロックにしか効果がありません。Firefox も同様の制限を設けています。これはバランス計算が行数に対して指数的にコストが増えるためで、長い本文段落に適用しても無視されます。

向いている要素

見出し(h1〜h3)、カードタイトル、ボタンラベル、キャプションなど短いテキスト

向いていない要素

本文の段落、記事本体、長い説明文など行数が多いテキスト

つまり text-wrap: balance は見出しやカード UI のような短いテキストに限定して使うプロパティです。本文段落には text-wrap: pretty のほうが適しています。

pretty との使い分け

balancepretty は目的が異なります。balance は全行の幅を均等にしようとしますが、pretty は最終行の孤立語(1〜2 単語だけ残る状態)を防ぐことに注力します。

/* 見出し系は balance */
h1, h2, h3, .card-title {
    text-wrap: balance;
}

/* 本文段落は pretty */
p, .body-text {
    text-wrap: pretty;
}

pretty には行数制限がないため、長文の段落にも安全に適用できます。Chrome 117 以降ではデフォルトで pretty 相当の挙動が有効になっているという情報もありますが、明示的に指定しておくほうが意図が伝わりやすいです。

日本語テキストでの注意点

英語は単語間のスペースで改行位置が決まりますが、日本語はどの文字間でも改行できるため、balance の効果がより顕著に現れます。ただし、日本語の場合は禁則処理(句読点が行頭に来ないようにする処理)との兼ね合いで、意図しない位置での改行が発生することがあります。

h2 {
    text-wrap: balance;
    word-break: auto-phrase;
}

word-break: auto-phrase は Chrome 119 で実装された値で、日本語の文節単位での改行を試みます。text-wrap: balance と組み合わせると、バランスを取りつつ自然な位置で改行される可能性が高まります。ただしこの値はまだ対応ブラウザが限定的なので、フォールバックを考慮する必要があります。

ブラウザ対応状況

2024 年時点での対応状況は以下のとおりです。

ブラウザbalancepretty
Chrome 114+対応対応
Firefox 121+対応未対応
Safari 17.5+対応未対応

Firefox と Safari は pretty に未対応ですが、未対応ブラウザでは単に auto と同じ挙動になるため、プログレッシブエンハンスメントとして安全に使えます。壊れることはありません。

既存プロジェクトへの導入

text-wrap: balance はレイアウトを壊すリスクがほぼないプロパティです。未対応ブラウザではデフォルトの折り返しが維持されるだけなので、既存の見出しスタイルに追加するだけで導入できます。

/* リセット CSS やベーススタイルに追加 */
h1, h2, h3, h4, h5, h6,
figcaption,
blockquote,
.card-title,
.hero-text {
    text-wrap: balance;
}

特に見出しは balance の恩恵を受けやすい要素です。プロジェクト全体のベーススタイルに入れておけば、個別の調整なしに見出しのバランスが改善されます。