flexboxのバグに立ち向かう(flexboxバグまとめ)

  • 817
    いいね
  • 2
    コメント
この記事は最終更新日から1年以上が経過しています。

image

flexbox使ってますか?バグつらいですね。必死に組んだレイアウトがIE11で崩れる様を見て、膝から崩れ落ちたことは何度もあります。

Solved by Flexboxの作者でもある、philipwaltonさんのflexbugsという素晴らしいflexboxのバグまとめがあるんですが、いかんせん分量が多くて読むのが辛いです。

そこで、今回はflexbugsに上がっているバグのスクショを一覧にしました(flexbugsはMITライセンス)。実際にバグってる表示と見比べることで、どのバグを食らっているのか、手がかりになるのではないでしょうか。

詳しい解説については、本家で見てください。また、IE10のみで起こるバグについては省略していますので、不幸にも対応の必要がある方はやっぱり本家を見てください。issue上の議論も参考になるでしょう。かなり雑に意訳してますので、趣旨が変わってしまっている項目とかあればご指摘ください。

本家: https://github.com/philipwalton/flexbugs

一覧

ブラウザ 状況 関係する要素/プロパティ
Safari アイテムが潰れた flex-shrink未指定
IE11 アイテムがコンテナをはみ出す align-items
IE11 アイテムが潰れた / min-height, min-widthが効かない min-height, min-width
IE11 アイテムがbasisに従わない flexショートハンド
IE11 imgが歪む imgをflexアイテム指定
IE11 アイテムがコンテナをはみ出す flexショートハンド, border, padding
IE11 calcが効かない flexショートハンド
Edge / FF / Safari button要素などにdisplay:flexが効かない button, fieldset
FF align-itemsが効かない align-items
Safari min-height, max-height, min-width, max-widthが効かない flex-wrap
Chrome / Safari / FF アイテムがコンテナをはみ出す flex-wrap

注)本文中の「コンテナ」「アイテム」について

スクリーンショット 2016-08-14 15.27.53.png

本文中でいう「コンテナ」「アイテム」は、flexコンテナとflexアイテムのことを指しています。

  • コンテナ
    • display: flexや、wrap指定などをする
    • 複数のアイテムを含む
  • アイテム
    • flex: 1 0 0%などの指定をする

1. アイテム潰れる問題(Safari)

Chrome

スクリーンショット 2016-08-14 15.08.00.png

Safari

スクリーンショット 2016-08-14 15.08.40.png

潰れてますね。

起きる条件

  • Safari

なぜ

  • コンテンツの最小サイズを尊重してくれない模様

どうすればいいのか

  • flex-shrinkに0を指定
  • flex-basisにautoを指定(デフォ値なので、指定がなければそのままでOK)

2. align-items:center はみ出す問題

Chrome

image

IE11

image

はみ出てますね。

起きる条件

  • IE10-11
  • flex-direction: column
  • アイテムにalign-items:centerが設定されている

どうすればいいのか

  • アイテムにmax-width:100%を設定する
  • アイテムにborderやpaddingが設定されている時、box-sizing:border-boxになっているか確認が必要
  • アイテムにmarginが設定されている時は上記の対処ではダメかも、padding使ったコンテナ要素を使ってください

3. min-height効かない問題

Chrome

image

IE11

image

body部分が潰れて、footerが重なってしまっている。

起きる条件

  • IE10-11
  • アイテムで min-height:100% とかやってる

なぜ

  • どうやらアイテムがコンテナの高さを知らない模様

どうすればいいのか

  • min-heightが必須でなければ、代わりにheightを使う
  • min-heightが必須の場合、コンテナにラッパー要素を追加する。いろんな理由により、ネストされたflexコンテナはバグの影響を受けない

4. flex: 1 0 0とかやると、flex-basisが無視される

Chrome

image

IE11

image

起きる条件

  • IE10-11
  • flex: 1 0 0の一番最後がflex-basisだけど、単位を付けないと無視されてしまう

なぜ

  • 2012年の時点では、flex-basisの単位を省略出来なかったので無視する仕様だった。IE11はまだその仕様に従っている

どうすればいいのか

  • flex: 1 0 0%のように単位を付けるだけ。
  • flexbugsのメンテナは「0pxを0に変換するCSSミニファイアとかあるから、%の方がいい」と言っている

5. imgのアスペクト比が維持されない

Chrome

image

IE11

image

800x200となっているのは画像です。imgがflexアイテムなんだけどIE11だとぐちゃっとなる。

起きる条件

  • IE10-11
  • imgに限らず起こるはずですが、たいていimgでしょう(筆者私見)。canvasとかでも起こるかも?

なぜ

  • 固有のアスペクト比を持っている要素は、比を保ったまま拡大されるべきだが、IEはそうなっていない。

どうすればいいのか

  • img要素をflexアイテムにしない。img要素の上にコンテナ要素を作り、その中に入れる。

7. flex-basisがborder-boxに対応してない

Chrome

image

IE10-11

image

borderとpadding分はみ出してしまっている。

起きる条件

  • IE10-11(いちいち書く意味が無いかもしれない)

なぜ

  • flex-basisってauto以外の指定があると、widthやheightのように動作するんだけど、border-box指定しててもborderやpadding分を計算に入れてくれない模様

どうすればいいのか

  • flex-basisに100%指定してる場合、flex-basisはautoにして、単にwidthやheightで100%指定すればよい。
  • または、paddingやborderを使っていないラッパー要素を作る。

8. flexショートハンドでのflex-basis指定がcalcに対応してない

これはスクショはいらないですよね…

起きる条件

  • IE10-11
  • flex:0 0 calc(100%/3)とかやると動かない
  • なおIE10はロングハンドにも対応してない

どうすればいいのか

  • 面倒だけどflex-basis(ロングハンド)で指定しましょう

9. buttonやfieldsetをflexコンテナにしたら崩れた

Chrome

image

Firefox 48.0

image

起きる条件

  • Edge / FF / Safari
  • 例えばbuttonをflexコンテナにする。スクショのような用途でやりがちですね。
  • なんとIEではちゃんとレンダリング出来ます

なぜ

  • button, fieldsetのような要素のブラウザ標準レンダラがflex定義と衝突している模様

どうすればいいのか

  • divのようなラッパー要素をbutton, fieldset内に入れればOK

10. align-items: baselineが効かない(Firefox)

Chrome

image

Firefox

image

起きる条件

  • FireFox
  • flexコンテナをネストさせている

どうすればいいのか

  • display: flexの代わりに、display: inline-flexを使うといいらしい。同時にwidth: 100%を指定する必要がある。

11. max, minサイズ指定がflex-wrap指定されている時に無視される(Safari)

Chrome

スクリーンショット 2016-08-14 15.18.51.png

Safari

スクリーンショット 2016-08-14 15.19.18.png

起きる条件

  • Safari
  • 例えば、アイテムのmin-width指定とコンテナのwrap指定を同時に使っている

どうすればいいのか

  • flex-basisを指定するしかないらしい
  • 例えば、min-width:200pxなら flex: 1 0 200pxのようにflex-basisを同時指定する

12. インライン要素がflexアイテムとして扱われない

IE11で試したけど、正常にレンダリングされているような…

14. wrap指定されたflexコンテナが、アイテムに応じたサイズにならない

IE11

image

Chrome

image

起きる条件

  • Chrome
  • Safari
  • Firefox

どうすればいいのか

まだワークアラウンドはないようです。コンテナのサイズを指定してしまうぐらいしか対策がなさそう。

まとめ

  • つらい
  • けど、見えてる地雷は大した地雷じゃない。ありがとうflexbugs
  • IE11のサポート期限は「2025年10月」までとみられる
  • IE11は初期からチェックしていった方がいい
  • flex-basisは罠がいっぱい
  • 最初からワークアラウンド付きのflexbox gridとかbootstrapとかが参考になるかもしれない

その他

https://github.com/luisrudge/postcss-flexbugs-fixes

postcssのflexbugs自動修正プラグインがあります。4, 6, 8は自動で直してくれますが、基本的に手で治す覚悟もまた必要でしょう。