勝手に回答シリーズ第3弾です。
今回の疑問
テキスト中に「ーーーーーー!!!!!!!!!!!!!!!!!!!」みたいなのがあると禁則処理の都合で包含ボックスの端で改行されずにボックス幅が無限に伸びちゃうんだけど、これ解消する方法ある?word-break: break-all;とかでもうまくいかんかった
僕なりの回答
これ、よくありますね。
サイト制作途中にダミーの文章を入れようと、「aaaaaaaaaaaaaaaaaaaa」みたいなのを入れておいたり、異常に長いURLを書いたり、テスト用のテキストをシステムから吐き出したりするとよくなりますね。
状況を再現
まずは状況を再現してみます。
ざっくりとした状況はこんな感じだと思います。※実際はtableの中の話なので後ほどちゃんと再現します。
これであれば直すのは簡単で、overflow-wrap(word-wrap)プロパティを用いて、break-wordという値を設定してあげます。
p要素に指定してもいいのですが、継承されるのでbody要素などに指定しまう方が簡潔かもしれません。
また、overflow-wrapプロパティとword-wrapプロパティとを併記しているのは、ブラウザのサポートの問題です。overflow-wrapが正しく、word-wrapの方が古いものです。
疑問の中に書かれて試されていたword-breakプロパティのbreak-allは、かなり強い指定で、すべての禁則処理が解除されてしまうため、とんでもない改行などになることがあります。
一方で、overflow-wrap(word-wrap)プロパティは穏やかなと言いますか、いい感じにしてくれます。※もっといい言い回しがあるとは思いますが…
基本的にはこれで解説は終わりなのですが、overflow-wrap(word-wrap)プロパティの指定だけでは上手く行かない場合があります。
それが今回の例に当てはまります。
overflow-wrap(word-wrap)プロパティの指定が効かない場合
とても便利そうなoverflow-wrap(word-wrap)プロパティですが、これが効かない場合もあります。
どんな時に効かないかと言えば、横幅が包含する要素の長さぴったりに自動調整される場合です。
具体的には以下のような場合です。
- displayプロパティがinline-blockになっている場合
- floatプロパティがleftもしくはrightになっている場合
- positionプロパティがabsoluteになっている場合
そして、これらに加え、tableのセルのように自動レイアウトが行われる場合も効かない場合の一つとなります。
では、再現してみます。
下のp要素の幅が400pxです。table要素にwidth:400px;
を指定しているにも関わらず、tableが伸びてしまっていますね。
CSSも同時に見て頂ければわかると思いますが、先ほどは上手くいっていたword-wrap:break-word;
及びoverflow-wrap:break-word;
を指定しているのにも関わらず、折り返しが上手くいっていません。
これがoverflow-wrap(word-wrap)プロパティの指定が効かない場合です。
※勘のいい方であれば「じゃあこのtdの中にpを入れれば効くんじゃない?」と思われると思いますが、それが残念ながら効きません。
では、どうすればよいか?
table要素以外の場合は、横幅を明示してあげれば上手くいきます。
横幅が自動計算の状態だと、どこで横幅が終わってどこで折り返せばいいのか計算する基準点がないので折り返せない(永遠に横幅が伸びるのが正義)となってしまっているだけなので、横幅を指定するだけで直ります。
固定値の横幅を指定したくない場合は、max-widthなどで最大横幅を指定してあげるといいでしょう。
さて、続いて本題のtable要素の場合ですが、通常ですとtable要素はtable-layoutというプロパティがautoの状態になっていて、自動レイアウトを行おうとします。
簡単に言えば、セルの内容量によっていい感じに調整するモードということです。
しかしながら、これがいい感じにならず「セルの横幅を自動で計算しようとする[table-layout:auto;]」のと「横幅が決まったら自動で折り返す[overflow-wrap(word-wrap):break-word;]」という二つの譲り合いが同居した結果、改行もされないし、tableの横幅も伸びるという結果になってしまうのです。
※どちらかと言えば、table側が譲り過ぎて、自身の横幅まで広げてしまっている感じですね。
という訳で、この譲り合いを止めるために、tableの自動レイアウトを止めてしまうというのが解決策となります。
具体的には、table-layoutプロパティがautoの状態であるものをfixedという値にしてあげます。
これでtableは指定してある400px以上には伸びず、その範囲内でoverflow-wrap(word-wrap)プロパティが計算されて折り返すようになります。
上記例の場合、列幅の指定を何もしていないので、三つの列はすべて同幅になります。
これらの幅を指定するにはcol要素などを用いて指定が可能ですが、それはまた別のお話になります。
これまで、なんとなくword-break:break-all;
を入れておけば直るかなと思っていた方も、word-wrap:break-word;overflow-wrap:break-word;
を入れれば直るかな、ただしtableの時は気を付けてtable-layout:fixed;
にしなきゃなと覚え直すと幸せになれるかもしれません。
あ、word-break:break-all;
とword-wrap:break-word;overflow-wrap:break-word;
を同時に指定すると、word-break:break-all;
のみの指定と同じになってしまうので要注意です。