【完全ガイド】CSSのテキストラッピングプロパティ解説 - overflow-wrap、word-break、white-spaceの使い分け

## はじめに
Webデザインにおいて、テキストの折り返しや改行の制御は重要な課題の一つです。CSSには複数のテキストラッピング関連プロパティが存在しますが、それぞれの特徴や使い分けが分かりにくいと感じる開発者も多いのではないでしょうか。

この記事では、実務でよく使用するテキストラッピングプロパティを中心に、その特徴と使い分けについて詳しく解説します。各プロパティの実践的な使用例とブラウザ対応状況も含めて、包括的に説明していきます。

## テキストラッピングプロパティが難しい理由

テキストラッピング関連のプロパティが理解しづらい主な理由として、以下が挙げられます。

1. **類似した名前のプロパティの存在**
   - overflow-wrap、word-break、text-wrapなど、似た名前のプロパティが複数存在
   - 各プロパティの役割の違いが直感的に理解しづらい

2. **使用頻度の偏り**
   - display、marginなどの基本的なプロパティと比較して使用頻度が低い
   - CSSフレームワークで自動的に設定されることも多く、詳細な動作を意識する機会が少ない


## 各プロパティについて
### テキストラッピング関連の中では、よく使用するプロパティ
#### overflow-wrap（word-wrap）
※ 元はword-wrapというプロパティでした。
<p class="codepen" data-height="300" data-theme-id="dark" data-default-tab="html,result" data-slug-hash="ZEgebae" data-pen-title="overflow-wrap_demo" data-preview="true" data-user="nunllunb-the-reactor" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/nunllunb-the-reactor/pen/ZEgebae">
  overflow-wrap_demo</a> by 長谷優作 (<a href="https://codepen.io/nunllunb-the-reactor">@nunllunb-the-reactor</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

overflow-wrap（以前のword-wrap）は、単語が要素の境界を超えそうな場合に、単語の途中で改行を許可するかどうかを制御します。

**使用場面**
- 長い単語やURLを含むテキストがコンテナからはみ出す可能性がある場合

**注意点**
- break-wordを使用すると、単語の途中で改行が発生する可能性があるため、可読性に影響を与える場合があります。

::: note
break-wordとanywhereは一見同じように見えますが、実際はbreak-wordは無理やり単語の途中で改行するのに対し、anywhereは可能な限り単語間の改行を試み、それが難しい場合は単語の途中で改行する感じになります。
またanywhereの方がbreak-allよりも新しい値の為、ブラウザ対応状況も異なります。

※ IEが廃止された現状では、どちらもそこまで対応状況が問題になるケースは少ないと思うので、anywhereを使用するのがいいかもしれません。
:::

**ブラウザ対応状況**
- モダンブラウザで広くサポートされています。

**代替案**
- word-break: break-all（より積極的に単語を分割します）
- hyphens: auto（可能な場合にハイフネーションを使用）

#### word-break
<p class="codepen" data-height="300" data-theme-id="dark" data-default-tab="html,result" data-slug-hash="bGXqVzp" data-pen-title="word-break_demo" data-preview="true" data-user="nunllunb-the-reactor" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/nunllunb-the-reactor/pen/bGXqVzp">
  word-break_demo</a> by 長谷優作 (<a href="https://codepen.io/nunllunb-the-reactor">@nunllunb-the-reactor</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

word-breakプロパティは、単語の途中での改行をどのように扱うかを制御します。

**使用場面**
- `break-all`: 長い英単語やURLを含むテキストで、どこでも改行を許可したい場合
- `keep-all`: アジア言語のテキストで、単語の途中での改行を防ぎたい場合
- `break-word`: overflow-wrap: break-wordと似た動作を期待する場合
- `auto-phrase`: 文の可読性を損なわないようにバランスを見ながら改行したい場合
::: note warn
現状auto-phraseの値はChromeの一部verなど、一部環境のみで使用できます。また対象言語も日本語のみでmdnにも記載されていない為、実用性は低いかもしれません。
ただ、とても便利な値のようなので、使用できるようになるのが楽しみです。
:::

**注意点**
- break-allは可読性を損なう可能性があるため、慎重に使用する必要があります。
- keep-allは、テキストがコンテナからはみ出す可能性があるため注意が必要です。
- break-wordは[非標準の値](https://developer.mozilla.org/ja/docs/Web/CSS/word-break#:~:text=%E7%94%9F%E6%88%90%E3%81%97%E3%81%BE%E3%81%99%E3%80%82-,%E3%83%A1%E3%83%A2%3A,-word%2Dbreak%3A%20break "非標準の値")であり、overflow-wrap: break-wordの使用が推奨されます。

**ブラウザ対応状況**
- モダンブラウザで広くサポートされています。
- break-word値のサポートは一部のブラウザに限られます。

**代替案**
- overflow-wrap: break-word or anywhere（単語の途中での改行を制御）
- hyphens: auto（可能な場合にハイフネーションを使用）

#### white-space

<p class="codepen" data-height="300" data-theme-id="dark" data-default-tab="html,result" data-slug-hash="qBerbXz" data-pen-title="Untitled" data-preview="true" data-user="nunllunb-the-reactor" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/nunllunb-the-reactor/pen/qBerbXz">
  Untitled</a> by 長谷優作 (<a href="https://codepen.io/nunllunb-the-reactor">@nunllunb-the-reactor</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

white-spaceプロパティは、要素内のスペースと改行の扱いを制御します。

**使用場面**
- preはコードブロックの表示したい場合
- nowrapは1行のテキストを強制的に表示したい場合
- pre-wrapは複数の空白を保持しつつ折り返したい場合

**注意点**
- nowrapを使用する際は、テキストがコンテナからはみ出す可能性があるため注意が必要です。
- preやpre-wrapを使用する際は、意図しない空白も表示されるため、ソーステキストに注意が必要です。(ソースコード整理のための改行もUIに反映されることがあります)

**ブラウザ対応状況**
- すべての主要ブラウザで完全にサポートされています。

**代替案**
- テキストの整形に``<pre>``タグを使用する
- JavaScriptを使用して空白や改行を制御する

#### text-overflow
<p class="codepen" data-height="300" data-theme-id="dark" data-default-tab="html,result" data-slug-hash="yLmMemQ" data-pen-title="text-overflow_demo" data-preview="true" data-user="nunllunb-the-reactor" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/nunllunb-the-reactor/pen/yLmMemQ">
  text-overflow_demo</a> by 長谷優作 (<a href="https://codepen.io/nunllunb-the-reactor">@nunllunb-the-reactor</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

**使用場面**
- `clip`: テキストが単純に切り取られます。
- `ellipsis`: テキストが省略記号（...）で切り詰められます。
- `"..."`: テキストがカスタムの文字列（この場合は "..."）で切り詰められます。

**注意点**
- `text-overflow`プロパティは、`overflow: hidden`と`white-space: nowrap`と組み合わせて使用する必要があります。
- このプロパティは単一行のテキストにのみ適用されます。複数行のテキストには効果がありません。
- カスタムの文字列（例：`"..."`）を使用する場合、ブラウザのサポートが限られている可能性があります。

**ブラウザ対応状況**
- `clip`と`ellipsis`の値は、ほぼすべての最新のブラウザ（Chrome、Firefox、Safari、Edge、Opera）でサポートされています。
- カスタム文字列（`"..."`など）のサポートは限定的で、一部のブラウザでは機能しない可能性があります。

**代替案**
- 複数行のテキストに対しては、`-webkit-line-clamp`と`-webkit-box-orient: vertical`を組み合わせて使用できます。
- JavaScriptを使用して、テキストを動的に切り詰め、カスタムの省略記号を追加することもできます。

#### text-wrap
<p class="codepen" data-height="300" data-theme-id="dark" data-default-tab="html,result" data-slug-hash="qBerbJB" data-pen-title="text-wrap_demo" data-preview="true" data-user="nunllunb-the-reactor" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/nunllunb-the-reactor/pen/qBerbJB">
  text-wrap_demo</a> by 長谷優作 (<a href="https://codepen.io/nunllunb-the-reactor">@nunllunb-the-reactor</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

**使用場面**
- `balance`: テキストの各行の長さをできるだけ均等にしようとします。短いテキストブロックに適しています。
- `pretty`: より美しい改行を作成しようとします。最後の行が短すぎたり、ハイフンが多すぎたりするのを避けます。
- `stable`: 異なるレンダリングパス間で一貫したラッピングを維持しようとします。動的コンテンツに適しています。
- `wrap`: デフォルトの動作です。通常のテキストラッピングを行います。

**注意点**
- このプロパティは実験的な段階にあり、ブラウザのサポートが限られています。
- 効果は、テキストの長さ、コンテナの幅、フォントなどによって変わる可能性があります。
- balanceとprettyは、短いテキストブロックで最も効果的です。

**ブラウザ対応状況**
- 2023年10月時点で、Chrome 99以降とEdge 99以降でサポートされています。
- Firefox、Safari、その他のブラウザではまだサポートされていません。

**代替案**
- text-align: justifyを使用して、テキストを両端揃えにする。
- JavaScriptライブラリ（例：Knuth-Plass行分割アルゴリズムの実装）を使用して、より高度なテキスト折り返しを実現する。

### 他のテキストラッピング関連のプロパティ
※自分は未だに実務では使用したことはないですが、制作物によっては使用する可能性はあるのかもしれません。

#### hyphens
<p class="codepen" data-height="300" data-theme-id="dark" data-default-tab="html,result" data-slug-hash="LYwWbJy" data-pen-title="hyphens_demo" data-preview="true" data-user="nunllunb-the-reactor" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/nunllunb-the-reactor/pen/LYwWbJy">
  hyphens_demo</a> by 長谷優作 (<a href="https://codepen.io/nunllunb-the-reactor">@nunllunb-the-reactor</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

**使用場面**
- `none`: ハイフネーションを無効にします。単語は分割されません。
- `auto`: ブラウザが自動的にハイフネーションを適用します。
- `manual`: 開発者が指定した位置（&shy;を使用）でのみハイフネーションが行われます。

**使用上の注意点**
- autoの効果は言語によって異なります。適切な言語設定（lang属性）が必要です。このデモでは英語（lang="en"）を使用しています。
- autoモードでも、すべての単語で適切なハイフネーションが行われるわけではありません。
- manualモードでは、開発者が適切な箇所にソフトハイフン（&shy;）を挿入する必要があります。

**ブラウザ対応状況**
- モダンブラウザ（Chrome、Firefox、Safari、Edge）で広くサポートされています。
- Internet Explorer 10以降でも部分的にサポートされていますが、完全な機能を期待できない場合があります。
- モバイルブラウザ（iOS Safari、Android Chrome）でもサポートされています。

**代替案**
- CSS: word-break: break-allを使用すると、単語の途中で改行できますが、読みやすさが損なわれる可能性があります。
- JavaScript: Hyphenator.jsのようなライブラリを使用して、クライアントサイドでハイフネーションを適用することができます。

#### line-break
<p class="codepen" data-height="300" data-theme-id="dark" data-default-tab="html,result" data-slug-hash="WNVpgmd" data-pen-title="line-break_demo" data-preview="true" data-user="nunllunb-the-reactor" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/nunllunb-the-reactor/pen/WNVpgmd">
  line-break_demo</a> by 長谷優作 (<a href="https://codepen.io/nunllunb-the-reactor">@nunllunb-the-reactor</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

**使用場面**
- `auto`: ブラウザのデフォルトの行折り返し規則を使用します。
- `loose`: より緩やかな行折り返し規則を適用します。
- `normal`: 標準的な行折り返し規則を適用します。
- `strict`: より厳格な行折り返し規則を適用します。

**使用上の注意点**
- このプロパティは主に中国語、日本語、韓国語（CJK）のテキストに影響します。
- 効果は主に句読点や特殊文字の周りでの改行動作に現れます。
- looseは可読性よりも空白の均一性を優先し、strictは可読性を優先します。

**ブラウザ対応状況**
- モダンブラウザ（Chrome、Firefox、Safari、Edge）で広くサポートされています。
- Internet Explorer ではサポートされていません。
- モバイルブラウザ（iOS Safari、Android Chrome）でもサポートされています。

**代替案**
- word-break: keep-allを使用すると、CJKテキストの単語の途中での改行を防ぐことができます。
- overflow-wrap: break-wordを使用すると、長い単語や文字列を強制的に折り返すことができます。


#### box-decoration-break
<p class="codepen" data-height="300" data-theme-id="dark" data-default-tab="html,result" data-slug-hash="NWQpObz" data-pen-title="box-decoration-break _demo" data-preview="true" data-user="nunllunb-the-reactor" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/nunllunb-the-reactor/pen/NWQpObz">
  box-decoration-break _demo</a> by 長谷優作 (<a href="https://codepen.io/nunllunb-the-reactor">@nunllunb-the-reactor</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

**使用場面**
- `slice`: デフォルトの動作です。ボーダーと背景が行の折り返し点で切り取られます。
- `clone`: 各行セグメントに対してボーダーと背景が複製されます。

**使用上の注意点**
- このプロパティは主にインラインレベルの要素（<span>など）に適用されます。
- cloneを使用すると、各行セグメントが独立して装飾されるため、視覚的な一貫性が向上しますが、パフォーマンスに影響を与える可能性があります。
- ボーダー、背景、パディング、マージンなどの装飾的な特性に影響します。

**ブラウザ対応状況**
- モダンブラウザ（Chrome、Firefox、Safari、Edge）で広くサポートされています。
- Internet Explorer ではサポートされていません。
- 一部のブラウザでは接頭辞（-webkit-）が必要な場合があります。

**代替案**
- 複数の<span>要素を使用して、各行を個別に装飾する。
- JavaScriptを使用して、行の折り返しを検出し、動的に要素を分割して個別に装飾する。

## まとめ
テキストラッピングプロパティは、一見似通っていても異なる役割を持っています。本記事で解説した内容を参考に、以下のポイントを押さえて実装することをお勧めします。

1. コンテンツの性質に応じた適切なプロパティの選択
    - 長文、URL、CJK文字など、テキストの特性を考慮
    - ブラウザ互換性を確認
    - 必要に応じて複数のプロパティを組み合わせる
2. 可読性とデザインのバランス
    - 過度な改行は避ける
    - ユーザーの閲覧環境を考慮
    - レスポンシブデザインへの対応
3. パフォーマンスへの配慮
    - 必要最小限のプロパティ使用
    - ブラウザの再描画への影響を考慮
    - 適切なフォールバックの実装


ご一読いただきありがとうございました:bow_tone1: