LoginSignup
62
39

More than 5 years have passed since last update.

`word-wrap:break-word;`がflexboxで効かない件

Last updated at Posted at 2016-09-11

やりたいこと

flexboxを使った「2カラムで、左側が固定カラム」であるレイアウトを考えます。
今、長い単語でもカラムからはみ出ない様にしたいので、word-wrap:break-word;を指定します。
word-break:break-all;でないことに、注意してください(後述参照)。

  <div id="parent">
    <div id="solid-column">
    SOLID
    supercalifragilisticexpialidocious
    </div>
    <div id="liquid-column">
    LIQUID
    supercalifragilisticexpialidocious
    </div>
  </div>

div {
    border:solid 1px;
}
#parent{
    display:flex;
    width:150px;
}
#solid-column {
    width:50px;
    word-wrap:break-word;
}
#liquid-column {
  flex:1;
  word-wrap:break-word;
}

問題

SOLIDカラムは折り返されましたが、LIQUIDカラムはボックスからはみ出てしまいました。

固定レイアウト.png

しかし、word-wrap:break-word;word-break:break-all;に変更したら、ボックスからはみ出ません。

#liquid-column {
  flex:1;
  word-break:break-all;
}

LIQUIDカラムが改行された.png

word-wrap:break-word;word-break:break-all;の違い

word-wrap:break-word;は適当な改行箇所がないとき、単語の途中で改行されます。
それに対して word-break:break-all;は、改行箇所の有無に関わらず、どの文字の間でも改行されます。
なので、見た目上word-wrap:break-word;を採用したいです。

※下記サイトが分かりやすいです。
http://nanto.asablo.jp/blog/2013/06/18/6869571#csswrap-shrink-to-fit
https://w3g.jp/blog/confusing_word-break_word-wrap

word-wrap:break-word;とflexboxの関係

下記ブログに詳しい説明が記述されていました。
http://nanto.asablo.jp/blog/2016/04/03/8063943

flex アイテム (display: flex または display: inline-flex を指定した要素の子要素) の最小幅 (flex アイテムが水平方向に並ぶ場合) は、(min-width プロパティで明示的に指定していなければ) flex アイテムの内容の最小幅または flex アイテムに width プロパティで明示的に指定された幅などのうち、最も小さいものになる (flex アイテムの幅がそれ以上縮むことはない) そうです。
ここで「内容の最小幅」を算出するときには word-wrap: break-word の影響を考慮できません (break-word は行ボックスの幅からあふれる単語に影響を与えるが、最小幅を算出しようという段階では行ボックスの幅も定まっていない)。なので、width も min-width も明示的に指定していない flex アイテムの内容に長い英単語があると、その単語の幅まで flex アイテムの幅が拡張されるということのようです (そして min-width が明示的に指定されていればそのようなことは起こらない)。仕様の注意書きには以下のように書かれています。

文書中の主要な領域に flex を使うなら、min-width: 12em のように明示的に最小幅を指定したほうがよい。そうでないと巨大な表や画像があったときに内容がはみ出して読みづらくなることがある。

min-widthを指定したら、改行されてボックスからはみ出なくなりました。

#liquid-column {
  flex:1;
  word-wrap:break-word;
  min-width:80px;
}

まとめ

  • flexboxではmin-widthを指定すること
  • 長い単語を折り返して表示するときは、word-break:break-all;でなくword-wrap:break-word;を指定すること

追記(word-wrap:break-word;が効かない場合)

flexbox以外でも、word-wrap:break-word;が効かないときがあります。

文章を折り返すかどうかを判断するには、文章を含んでいる領域の幅を先に知る必要があります。
「文章量によって領域の幅を決める」設定の場合、領域の幅が分からないから「折り変えすことはできない」のだと思います。

内容にぴったりと合うように縮んだ幅

display:inline-block;, float:left;, float:right;, position:absolute;などが指定された要素では、word-wrap:break-word;が効きません。
widthmax-widthなどで幅を指定すれば、効くようになります。

display:inline-block;, float:left;, float:right;, position:absolute;などのプロパティと値が指定されたshrink-to-fit widthの場合は、幅(width)や最大幅(max-width)を明示してやれば良いだけです。width:auto;のために、その内容によって自身の幅が決められていたのを、width:100%;のように幅を決めることで、単語の途中で折り返さないと行ボックスの幅からあふれるかどうかを計算できるようになります。

自動レイアウトアルゴリズム(table-layout:auto;)を使用しているテーブルセル

table-layout : fixed;を指定し、表全体の幅も指定すれば、効きます。
また、word-break:break-all;は、自動レイアウトアルゴリズムでも効きます。

一切の禁則処理を解除するword-break:break-all;は自動レイアウトアルゴリズム(table-layout:auto;)を使用しているテーブルセル(display:table-cell;)のスタイル状況下でも関係なく折り返す位置になれば折り返します。そのため、自動レイアウトアルゴリズム(table-layout:auto;)を使用しているテーブルセル(display:table-cell;)では、本来はword-wrap:break-word;(overflow-wrap:break-word;)が用いたかったが効かないからという勘違いのもと(正確にはあふれるかどうかが計算できていないだけ)でword-break:break-all;が用いられてしまうことがよくあります。

62
39
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
62
39