理系学生日記

おまえはいつまで学生気分なのか

自動折り返しにまつわるCSS word-break と overflow-wrap

とにもかくにもレスポンシブウェブデザイン(RWD)とやらで HTML やら CSS やらと格闘を続けております。

なんかさー! ブラウザ依存でさー!! 変なレイアウトになったりするしさー!!!! ブラウザだけじゃなくさー!!!!! OS でもレイアウトが変になっちゃったりするしさー!!!!!!!!! とにかくさー!!!!!!!!!!!! 同じ見た目を全ブラウザで揃えようっていうのがそもそもの間違いなんじゃないかなー!!!!!!!!!!!!!!!!!!!! 解釈は自由っていうかさー!!!!!!!!!!!!!!!!!!! ダイバーシティーって言うかさー!!!!!!!!!!!!!!!!!!!!!!!!

それで

そういうわけで RWD なんて関係のないところでの CSS3 の話題です。 ちょっと苦しまされたのが、CSS3 の word-breakoverflow-wrap (word-wrap) についてです。 こいつら、似たような感じに見えるんですが、word-break については禁則処理の設定という意味合いで、overflow-wrap (word-wrap) については、単語の途中で折り返さないと描画範囲から overflow してしまうときに単語の中に改行を入れて良いかどうかを制御します。

もうちょっと詳しくみていきましょう。

word-break

word-break は、禁則処理を設定する(keep-all)か解除する(break-all)のかを選択するプロパティです。 なんか良くわからないように聞こえますが、ここの例なんかが分かりやすい。

f:id:kiririmode:20161105190649p:plain (CSS Text Module Level 3 より)

これは日本語の文章で、敢えて禁則処理をしないケースです。Caption という一語が、禁則処理をされずに途中で折り返されていることが分かります。

overflow-wrap (word-wrap)

overflow-wrap は、単語を折り返さないと描画領域をはみ出してしまうケースにおいて、その単語を途中で折り返すか否かを設定するプロパティです。可能な限り禁則処理は有効にしたままっていうところが、word-break と異なります。

それでは違いを具体的に見てみましょう

ここでは、以下のような HTML を用意しました。

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8">
    <title>word-break</title>
    <style>
      div {
        width: 300px;
        margin: 10px;
        border: 1px solid blue;
        text-decoration: underline; }
      }
      .normal { word-break: normal; }
      .break-all { word-break: break-all; }
      .wrap-normal {
        overflow-wrap: normal;
        word-wrap: normal;
      }
      .wrap-break-word {
        overflow-wrap: break-word;
        word-wrap: break-word;
      }
    </style>
  </head>
  <body>
  (後述)
  </body>
</html>

div タグには、分かりやすいように描画領域に線を引き、文字には下線を引くようにしています。 その他、word-breakoverflow-wrap の値を変えた class を用意しました。

それぞれの class を適用していくのは、以下のような HTML です。日本語と英語、それと意地悪な感じで &nbsp の連続したのを用意してみました。 &nbsp; は non-breaking space の略で、自動的な改行を防ぐというのがその意味合いです。 wikipedia:ノーブレークスペース

<p>
  あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをん <br />
</p>
<p>
  abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ
</p>
<p>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hello world
</p>

1. word-break: normal

Chrome

f:id:kiririmode:20161105191913p:plain

Safari

f:id:kiririmode:20161105195913p:plain

Firefox

f:id:kiririmode:20161105200252p:plain

禁則処理が有効化されているため、英文字の連続は一語と見做され、折り返しがなされません。これは &nbsp;の連続についても同様でした。

2. word-break: break-all

Chrome

f:id:kiririmode:20161105191924p:plain

Safari

f:id:kiririmode:20161105195926p:plain

Firefox

f:id:kiririmode:20161105200302p:plain

禁則処理が無効化された結果として、英文字の連続にも強制的な折り返しがされています。 一方で、Chrome については &nbsp;の連続、および、&nbsp に後続する英文字については適用されておらず、描画領域を飛び出していることが分かります。 Chrome おい! Chrome !!!!!!

3. overflow-wrap: normal

Chrome

f:id:kiririmode:20161105191933p:plain

Safari

f:id:kiririmode:20161105195939p:plain

Firefox

f:id:kiririmode:20161105200321p:plain

これは word-break: normal の結果と同じになりました。

4. overflow-wrap: break-word

Chrome

f:id:kiririmode:20161105191942p:plain

Safari

f:id:kiririmode:20161105195957p:plain

Firefox

f:id:kiririmode:20161105200331p:plain

英文字の連続が描画領域を飛び出さないように、適切な折り返しがはいっています。 また、それは、&nbsp; の連続にも適用されています。

というわけで、overflow-wrap: break-word だといけそうな雰囲気でしたが、Android OS の Chrome だと &nbsp; の連続が折り返されなかったりしたのでもうダメです。&nbsp; についてはその意味合いとして折り返し許可しないんだし、折り返しが必要なところで使用する方がダメなのではないか。