12k
All articles

見出しが不適切な位置で改行されるのを防ぐ

見出しの改行崩れや長いURLを、適切なCSSとHTMLで修正: nbsp, wbr, overflow-wrap:anywhere, word-break:break-all, hyphens:auto, text-wrap。

OpenReplay Team
OpenReplay Team
見出しが不適切な位置で改行されるのを防ぐ

短い単語の直後で改行される見出し、最終行に取り残された1単語、コンテナの幅を押し広げる長いURL——これらは3つの異なる欠陥であり、それぞれに通常は異なるCSSまたはHTMLの修正が必要になります。

これらには厄介な共通点もあります。特定のコンテナ幅でしか発生しないのです。デザイナーは384pxのスマートフォンで崩れた見出しをスクリーンショットに撮りますが、あなたがデスクトップ幅でページを開くと何も問題がないように見えます。不適切な改行は、誰もテストしていない狭いビューポート帯に潜んでいる傾向があります。だからこそ、実際のユーザーがブラウジングした幅でセッションリプレイを確認することが、発生した通りの欠陥を目にする最速の方法になることが多いのです。

この記事では、目に見える各問題、それを修正するツール、そして次回に適切なツールを選ぶための考え方を順に解説します。

要点

  • 長いURLやトークンには break-word ではなく overflow-wrap: anywhere を使いましょう。anywhere は緊急時の改行位置を min-content サイズ計算に含めるため、flexアイテムやgridアイテムが実際に縮小できるようになります。
  • ある地点での改行を禁止するには、改行可能な文字をその非改行版に置き換えます。スペースには  (U+00A0)、ハイフンには ‑(U+2011)、スペースがまったくない箇所には ⁠(U+2060)を使います。
  • ある地点での改行を許可するには、改行のみを行う <wbr> か、改行が採用されるまでは非表示で、採用されるとハイフンを描画する &shy;(U+00AD)を使います。
  • word-break: break-all は通常の単語を各行の終わりで切断します。単語境界に意味がないハッシュやトークンに限定して使いましょう。
  • text-wrap: balance は既存の改行位置を再配分するだけで、要素のサイズを変更することはありません。またブラウザは短いブロックに制限しており、Chromiumでは6行、Firefoxでは10行までです。

ある地点での改行を禁止するには?

ブラウザが特定の箇所で改行するのを止めるには、改行可能な文字をその非改行版に置き換えます。ノーブレークスペース(&nbsp;、U+00A0)は、2つの単語の間の通常のスペースをブラウザが改行できないスペースに置き換えることで、両者を同じ行に保ちます。「of」の直後で折り返されてしまう見出しや、製品名が行をまたいで分割されてしまう場合の修正方法です。

テキストはスペースがない箇所でも改行されることがあり、最も多いのはハイフンの後です。ワードジョイナー(U+2060、大文字小文字を区別する&NoBreak; 名前付き参照として記述)は幅を一切追加せずに改行を禁止し、非改行ハイフン(U+2011、&#8209;、名前付き実体参照はありません)は改行位置にならないハイフンを描画します。

<h2>Shipping the new editor to&nbsp;everyone</h2>
<p>Take the exit for I&#8209;95 north.</p>

ある地点での改行を許可するには?

これと鏡像の関係にある問題が、改行させたいけれども自分が選んだ箇所でのみ改行させたい長い文字列です。<wbr> 要素を挿入すると、行を終えられる場所をブラウザにもう1箇所提供でき、改行が採用されても目に見えるものは何も挿入されません。ソフトハイフン &shy;(U+00AD)は同種の改行機会を示しますが、改行が採用されるとハイフンを描画します。それまでは非表示です。デフォルトの hyphens: manual の下で動作するため、何かが hyphens: none を設定している場合にのみ機能しなくなります。

<p>https://docs.example.com<wbr>/reference<wbr>/text-wrapping</p>
<p>The rise of hyper&shy;modularization</p>

表示されるURLや識別子には <wbr> を、実際の単語には &shy; を使いましょう。

分割できない長い文字列: overflow-wrap: anywhere

ユーザー生成コンテンツ、長いURL、手作業で注釈を付けられないトークンには、overflow-wrap: anywhere を設定して、最終手段としてブラウザに改行させます。決定的に重要な詳細は内在サイズ(intrinsic sizing)です。どちらの値もブラウザが長い単語を分割できるようにしますが、それらの緊急改行位置を要素の min-content 幅に反映させるのはanywhereだけです。break-word では、その幅は分割されていない文字列全体の長さのままになります。これが、長いURLを含むflexアイテムが break-word では依然として縮小を拒否してレイアウトを破壊するのに、anywhere では正しく縮小する理由です。CSS Text Level 4では、この1点の違いを除いて2つの値を同一に定義しており、実際に人々が直面するのはまさにこの違いです。

.card { display: flex; gap: 1rem; }
.card-body {
  /* break-word leaves min-content at the full URL width */
  overflow-wrap: anywhere;
}

anywhere の値はすべてのモダンエンジンで動作し、Safariが最後に15.4(2022年3月)で対応しました。古いコードベースでは、非推奨の word-break: break-word が残っていることがあります。これは word-break 自体を通常の動作のままにしつつ、折り返しは overflow-wrap: anywhere とまったく同じ結果になります。置き換えましょう。

word-break: break-all はどこで使うべきか?

word-break: break-allは、行のスペースが尽きた場所ならどこでも、単語の途中であっても改行を入れます。ハイフンは追加されず、単語を無傷に保つために単語全体を次の行に送ることもしないため、通常の散文はすべての行末で切断されてしまいます。したがって散文には不適切なツールであり、単語境界に意味がない文字列——コミットハッシュ、APIキー、テーブルセル内のトークンなど——には適切なツールです。keep-all の値はCJKにおける逆のニーズに応え、文字間の改行を抑制します。

.commit-hash {
  font-family: monospace;
  word-break: break-all; /* never on prose */
}

狭いカラム: hyphens: auto と lang 属性

狭いカラムが単語の途中での改行を強制する場面では、辞書的に正しいハイフネーション位置のほうが、力任せの切断よりもはるかに読みやすくなります。hyphens: autoは、その要素または祖先要素のいずれかに lang 属性が付いていなければ何もしません。言語ごとに単語の分割方法が異なるため、ブラウザはハイフネーションを行う前にどの言語を参照すべきかを知る必要があります。このプロパティはBaselineで広く利用可能(Widely available)であり、2023年9月以降、各ブラウザでプレフィックスなしで動作しています。

<aside lang="en" class="sidebar-note">Uncharacteristically long words wrap cleanly here.</aside>
.sidebar-note { hyphens: auto; }

見出しと段落: text-wrap の balance と pretty

見出しの最終行に単語が1つだけ残る場合、text-wrap: balanceが既存の改行位置の中から異なる選択をすることで行の長さを均等化します。新しい改行位置を作ることはなく、要素のボックスサイズも変更しないため、バランス調整された見出しは元の幅を維持します。バランス調整はコストが高いため、ブラウザは制限を設けています。Chromiumは6行、Firefoxは10行で打ち切り、それより長いブロックは通常どおり折り返されます。text-wrap: pretty は本文テキストを対象とし、より多くのレイアウト処理を費やして孤立語を避けます。Chromiumとバージョン26で対応したSafariでサポートされていますが、Firefoxではまだ未対応です。text-wrap プロパティ自体は2024年3月以降、最新のブラウザ全体で動作しています。

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

問題別ツール早見表

目に見える欠陥ツール
短い単語の後で見出しが改行される一緒に保ちたい単語の間に &nbsp;
保持すべきハイフンで改行が起きる&#8209;(非改行ハイフン)または &NoBreak;
長い文字列を選んだ1箇所で改行したい<wbr>(ハイフンなし)または &shy;(使用時にハイフン)
URLやトークンがカードやグリッドセルを広げるoverflow-wrap: anywhere
ハッシュがテーブルセルからあふれるword-break: break-all
狭いカラムが単語を音節の途中で切断するhyphens: autolang 属性
見出しの最終行に単語が1つだけtext-wrap: balance
本文段落の孤立語text-wrap: pretty

このツールキット全体に通底するパターンはこうです。その欠陥が「改行の禁止」を必要としているのか、「改行の許可」なのか、それとも「全面的な折り返し戦略」なのかを見極め、それを修正できる最も限定的なツールを適用する。妥当なベースラインは、ユーザーコンテンツを保持するコンテナには overflow-wrap: anywhere、見出しには balance、段落には pretty を設定することです。文字レベルの実体参照は、その後にデザイナーが指摘する個別の改行のために取っておきましょう。

FAQ

overflow-wrap と word-break の違いは?

overflow-wrap は、単語が長すぎて1行に収まらない場合にのみ介入し、それ以外はすべて通常どおり折り返されます。word-break: break-all は要素全体の戦略を変更し、行のスペースが尽きた場所ならどこでも単語を分割します。通常の散文の中に時折現れる長いURLには overflow-wrap: anywhere を使い、word-break: break-all は単語境界に意味がないハッシュやトークンにのみ使いましょう。

word-wrap は overflow-wrap と同じですか?

はい。このプロパティは word-wrap という Microsoft の拡張として登場し、後に overflow-wrap という標準名を得ましたが、ブラウザは今でも旧名を新名のエイリアスとして受け付けます。新しいコードでは overflow-wrap と書きましょう。現行ブラウザではフォールバックとしての word-wrap は不要であり、両方を宣言しているスタイルシートは同じプロパティを2回設定しているだけです。

wbr 要素の代わりにゼロ幅スペースを使うべきなのはどんなときですか?

CMS に保存されているコンテンツや API から返されるコンテンツなど、文字列自体しか変更できない場合にはゼロ幅スペース(U+200B、​ 参照として記述)を使い、HTML を制御できる場合には wbr 要素を使いましょう。ゼロ幅スペースはテキスト内に残る不可視文字なので、コピー&ペーストで一緒に運ばれ、完全一致検索を妨げる可能性があります。

text-wrap: pretty をサポートしないブラウザでは何が起きますか?

宣言は単純に無視され、テキストはデフォルトの行単位アルゴリズムで折り返されるため、見た目が崩れることはありません。CSS は値を認識できない宣言を破棄するので、text-wrap: pretty と text-wrap: balance は安全なプログレッシブ・エンハンスメントになります。サポートするブラウザではより良い改行が得られ、それ以外では従来どおりに描画されます。機能クエリやフォールバック宣言は必要ありません。

Open-source session replay

Gain control over your UX

See how users are using your site as if you were sitting next to them, learn and iterate faster with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data.

Star on GitHub12k

We use cookies to improve your experience. By using our site, you accept cookies.