Edited at

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

More than 1 year has passed since last update.

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)

  • Safari10にて修正済み(つまり、SierraとiOS 10以降では対応不要)


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は自動で直してくれますが、基本的に手で治す覚悟もまた必要でしょう。