flexbox レイアウトで内容がはみ出す理由 ― 2016年04月03日 02時23分
「flex box layoutで中に長いテキストなどを含む幅可変要素のレイアウト - くらげだらけ」という記事が興味深いです。過去に「長い英単語を途中で折り返したいときの CSS の指定方法」にて、word-wrap: break-word
と display: inline-block
などの組み合わせには注意が必要 (word-wrap
の指定が効かないように見えることがある) と述べたのですが、似たようなことが display: flex
にも言えるようです。
この挙動は認識していなかったので CSS Flexible Box Layout Module Level 1 (flexbox 仕様草案、2016 年 4 月 2 日時点のもの) を見てみたところ、「4.5. Implied Minimum Size of Flex Items」(flex アイテムの暗黙的な最小サイズ) の項に記述がありました。
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
のように明示的に最小幅を指定したほうがよい。そうでないと巨大な表や画像があったときに内容がはみ出して読みづらくなることがある。
Note - 4.5. Implied Minimum Size of Flex Items - CSS Flexible Box Layout Module Level 1 より抄訳
ではなぜこのような仕様になっているのでしょうか? 最初はパフォーマンス上の理由かと思いましたがそうではなく (flex アイテムの内容が膨大なときには、むしろパフォーマンスに悪影響を及ぼしうる)、製作者の意図しない奇妙な表示結果を避けるためだそうです。fantasai (flexbox 仕様編集者の一人) による暗黙的な最小サイズの解説に、どんな場面でどんな挙動を想定しているかの例も載っていました。主には「複数のナビゲーション項目を flex で並べたいが、画面幅が狭くて収まりきらない場合」の救済措置を意図しているようです。
奇妙な表示結果を避けるための仕様が、ある場面では逆に制作者の意図しない「奇妙な表示結果」を生み出しているというのが面白いですね。
補足: CSS 仕様の導入の経緯の調べ方
この記事を書くにあたって特定の CSS 仕様が導入された経緯について調べたのですが、その具体的な手順は以下の通りです。
- 何はともあれまずは最新の仕様草案を確認する。
- CSS の各仕様の編集者草案へのリンクは CSS Working Group Editor Drafts にまとまっている。
- flexbox 仕様の編集者草案を見る。
- 2016 年 4 月 1 日に生成されたもの。内容としては 2016 年 3 月 1 日付け勧告候補とほぼ同じと思われる。
- flexbox 仕様草案を斜め読みしていく。
- 「4.5. Implied Minimum Size of Flex Items」で
min-width
とmin-height
プロパティを再定義しているのを見つける。 - 「9. Flex Layout Algorithm」もざっと追おうとするが、分量も多く複雑なので断念。
- 大元の記事に関する仕様草案の記述個所はわかったが、なぜそのような仕様になっているのかはわからない。
- 「4.5. Implied Minimum Size of Flex Items」で
- その仕様がいつ導入されたのかを確認する。
- 仕様草案冒頭の Previous Versions から過去の草案を見ていき、2012 年 6 月 12 日付け草案から「Implied Minimum Size of Flex Items」の項が登場しているのを確認。
- 2012 年 3 月 22 日付け草案には存在しない。
- メーリングリストでの議論を追う。
- 仕様草案の Status of this document から、W3C CSS メーリングリストのアーカイブページに移動。
- 2012 年 3月、4 月、5 月のメール一覧ページ (by thread) を見る。
- メール一覧ページを「css3-flexbox」でページ内検索し、関連しそうなスレッドがないか探すも見つからない
- 「[css3-flexbox] implied minimum size of flex items」というのはあったがフォローアップ的な内容のみ。
- 件名に含まれる文字列が「css-flexbox」になっているのもあると後から気づく。
- 仕様草案の Status of this document から、W3C CSS メーリングリストのアーカイブページに移動。
- 検索する。
- メーリングリストはあきらめて「implied minimum flexbox」でググったら、まさに求めていた情報であるところの「Flexbox Implied Minimum Size」が見つかる。
- その文書内に更新日時が書かれていないが、URL の階層をひとつ上がってみると 2013 年 7 月 24 日更新とわかる。
- メーリングリストはあきらめて「implied minimum flexbox」でググったら、まさに求めていた情報であるところの「Flexbox Implied Minimum Size」が見つかる。
- ミーティングでの議論を追う。
- 仕様の方針決定は CSS ワーキンググループ (CSS WG) のミーティングでなされることも多いので、「CSS WG MTG」でググるもミーティング一覧が出てこない。
- 「CSS WG F2F」(F2F は Face-to-Face の略、実際に顔を突き合わせてのミーティング) でググったらミーティング一覧ページが出てきた。
- 時期的に近そうな 2012 年 5 月ハンブルグ F2F の議事録 (Part I) を見たところ、議題「Flexbox: Flex Property and Flex Sizing」の中に「Next Issue: Implied minimum size of flexbox items」という項目があった。
- ここで flex アイテムの最小幅の問題について取り上げられている。
コメント
_ yuji ― 2016年09月11日 12時14分
_ (未記入) ― 2018年08月14日 01時21分
ブラウザの幅を狭めてもflexアイテムが縮まずに、ブラウザからはみ出してしまう症状があって、全く原因が分からずにいました。flexアイテムに最小幅があり、しかもその最小幅に「flexアイテム内の要素の幅」が採用される場合があるとは思いませんでした!
ありがとうございました!
※メールアドレスとURLの入力は必須ではありません。 入力されたメールアドレスは記事に反映されず、ブログの管理者のみが参照できます。
※投稿には管理者が設定した質問に答える必要があります。
トラックバック
このエントリのトラックバックURL: http://nanto.asablo.jp/blog/2016/04/03/8063943/tb
ありがとうございます。