white-space の各プロパティの挙動の違い

# はじめに

改行が効かない！というときに思いつく CSS プロパティは `white-space` かと思います。その時にだいたい `pre-wrap` か `pre-line` を使用するのではないかと思います。

この両者の違いを理解できていなかったので、今回は他のプロパティも含め、触れていきたいと思います。

# white-space プロパティとは

このプロパティでは名前の通り、HTMLコード内のホワイトスペースをどのように表示させるかを決めることができます。

どのような種類があるかというと、以下の5つのようです。

- タブ (TAB)
- 改行 (LF : Line Feed)
- ページ送り (FF : Form Feed)
- キャリッジリターン (CR: Carriage Return)
- 空白 (SPACE)

キャリッジリターンは「カーソルを先頭に戻る」を意味する制御文字だそうです。

そのまま先頭に戻したら、また同じ行に入力していくことになってしまうので、改行 (LF) と組み合わせて使うのが普通のようです。

# それぞれの値の動きを見てみよう

設定できる値としては以下があります。

- `normal` (初期値)
- `no-wrap`
- `pre`
- `pre-wrap`
- `pre-line`
- `break-spaces`

いろいろ言葉で説明するよりも実際の動きを見た方がわかりやすいと思うので、以下のような HTML で実際に動きを見てみたいと思います。

```html
<div class="example normal">
  <strong>white-space: normal</strong><br>
  これはテストです。    複数の空白文字を入力しても、表示される際には1つの空白にまとめられます。親要素から溢れると自動的に折り返されます。
改行すると空白1つ入るだけで改行されません。                                        
行末の空白は除去されます。
</div>
```

見たい観点としては以下です。

- `<br>` でどのような挙動になるか
- 複数の空白文字がどうなっているか
- 自動的に折り返されるか
- 改行ができるか
- 行末の空白はどうなっているか

# normal

以下のように、複数の空白を一つの空白にまとめてくれます。明示的に指定していますが、これはデフォルトで当たっているので、指定しなくても同じ動きです。

また、ボックスから溢れそうになると自動的に折り返してくれます。

しかし、明示的に改行した場合、空白が一つ入るだけで改行されていないことがわかります。

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="JoPRKNR" data-pen-title="white-space normal" data-user="yamataikoku0114" 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/yamataikoku0114/pen/JoPRKNR">
white-space normal</a> by yamataikoku0114 (<a href="https://codepen.io/yamataikoku0114">@yamataikoku0114</a>)
on <a href="[https://codepen.io](https://codepen.io/)">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

- `<br>` でどのような挙動になるか

`<br>` では改行されています

- 複数の空白文字がどうなっているか

統合されて1つの空白文字になっています

- 自動的に折り返されるか

折り返されています

- 改行ができるか

改行すると空白が1つ入っているだけで、行末の空白は除去されています

- 行末の空白はどうなっているか

行末の空白も除去されて、1つの空白になっています

# no-wrap

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="dPbpXvv" data-pen-title="white-space nowrap" data-user="yamataikoku0114" 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/yamataikoku0114/pen/dPbpXvv">
white-space nowrap</a> by yamataikoku0114 (<a href="https://codepen.io/yamataikoku0114">@yamataikoku0114</a>)
on <a href="[https://codepen.io](https://codepen.io/)">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

自動的に折り返されないこと以外は `normal` と同じなので、説明を省きます！

# pre

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="NPKRrjE" data-pen-title="white-space pre" data-user="yamataikoku0114" 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/yamataikoku0114/pen/NPKRrjE">
white-space pre</a> by yamataikoku0114 (<a href="https://codepen.io/yamataikoku0114">@yamataikoku0114</a>)
on <a href="[https://codepen.io](https://codepen.io/)">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

- `<br>` でどのような挙動になるか

`<br>` で改行されているかつ、空行が入っていることがわかります。

- 複数の空白文字がどうなっているか

統合されずに空白文字分だけ表示されています

- 自動的に折り返されるか

折返されません

- 改行ができるか

改行できています

- 行末の空白はどうなっているか

行末の空白も除去されて、1つの空白になっています

# pre-wrap

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="jENMrXg" data-pen-title="white-space pre-wrap" data-user="yamataikoku0114" 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/yamataikoku0114/pen/jENMrXg">
white-space pre-wrap</a> by yamataikoku0114 (<a href="https://codepen.io/yamataikoku0114">@yamataikoku0114</a>)
on <a href="[https://codepen.io](https://codepen.io/)">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

- `<br>` でどのような挙動になるか

こちらも `pre` と同じように `<br>` で改行されているかつ、空行が入っていることがわかります。

- 複数の空白文字がどうなっているか

統合されずに空白文字分だけ表示されています

- 自動的に折り返されるか

折返されます

- 改行ができるか

改行できています

- 行末の空白はどうなっているか

除去されています

# pre-line

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="dPbpXrJ" data-pen-title="Untitled" data-user="yamataikoku0114" 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/yamataikoku0114/pen/dPbpXrJ">
Untitled</a> by yamataikoku0114 (<a href="https://codepen.io/yamataikoku0114">@yamataikoku0114</a>)
on <a href="[https://codepen.io](https://codepen.io/)">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

- `<br>` でどのような挙動になるか

こちらも `pre` と `pre-wrap` と同じように `<br>` で改行されているかつ、空行が入っていることがわかります。

- 複数の空白文字がどうなっているか

統合されています。

- 自動的に折り返されるか

折返されます

- 改行ができるか

改行できています

- 行末の空白はどうなっているか

除去されています

追加でわかったのは、文頭のスペースも除去されているということです。

これに関しては、MDN で記載はされていなさそうですが、こういった動きにもなるようです。

# break-spaces

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="PwYGzgx" data-pen-title="Untitled" data-user="yamataikoku0114" 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/yamataikoku0114/pen/PwYGzgx">
Untitled</a> by yamataikoku0114 (<a href="https://codepen.io/yamataikoku0114">@yamataikoku0114</a>)
on <a href="[https://codepen.io](https://codepen.io/)">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

- `<br>` でどのような挙動になるか

こちらも `pre` と `pre-wrap` , `pre-line` と同じように `<br>` で改行されているかつ、空行が入っていることがわかります。

- 複数の空白文字がどうなっているか

統合されずに空白文字分だけ表示されています

- 自動的に折り返されるか

折返されます

- 改行ができるか

改行できています

- 行末の空白はどうなっているか

除去されないので、ボックスの大きさに影響してきます。

`pre-wrap` との違いは MDN にも記載されていますが、行末の空白を除去するか、しないかという点です。

# まとめ

自分が思っているよりも各プロパティそれぞれで動きが結構異なっていて面白かったです。

改行が効かない時に `pre-wrap` と `pre-line` どちらを使った方が良いのかという話に関しては、これはケースバイケースによりそうだなと個人的には感じました。

個人的な使い分けとしては、文頭に空白を入れたいか入れたくないかで分けるのが良いのではないかなと整理しました。

文頭に空白を入れたい場合は `pre-wrap` で、文頭に空白を入れたくないなど基本的に空白を許容しないケースは `pre-line` を使って、改行コードで改行されるようにしてあげれば良さそうと思ったので、今後取り入れていければと思います！

最後まで読んでくださりありがとうございました。

何が間違いがあればご指摘くださると助かります。