flexboxのプロパティの組み合わせを比較できるカタログが欲しいなーと思ったので作ってみました。
各プロパティーの値がどのように解釈されるか、ブラウザ間での違いなどが分かります。
あれもこれもと入れていたら無駄に長くなりました。
2017年8月17日追記
Safari の flex-basis の挙動が Chrome、Firefox、Edge と同じなっていたので、記事とサンプルをアップデートしました。
See the Pen Case Studies of Flexbox by Keita Okamoto (@all-user) on CodePen.
縦のストライプの幅が10px、flexコンテナの幅が360pxとなっていて、flexアイテムとそのコンテンツの大きさはそれぞれのラベルに表示されます。
コンテナの上には当てているスタイルの要約と最終的なサイズを割り出す計算式があります。
全ブラウザで結果が同じ場合は緑、ブラウザ間で結果に差異がある場合は赤の文字になっています。

一応仕様的にはこうなるべきだろうという計算式を書いているつもりですが、解釈が間違っているかも知れません。
なんか違うなと思ったら教えていただけると助かります。
ベストプラクティス(暫定)
flexboxの各アイテムが最終的にどのサイズで描画されるのかは領域の分配ルールに様々な要素が絡んでいます。
そのため、適当にプロパティを組み合わせていくと、なかなか思い通りのサイズになりません。
スコープを絞るために話をflex-direction: rowに限定するとして、サイズの計算に影響を与えるプロパティはこれだけあります。
flex-shrinkflex-growflex-basiswidthmin-widthmax-widthmarginpaddingbox-sizing
さらにブラウザ間の誤差やflexboxの抱える様々なバグを考慮して全てをコントロールするのはかなり難しいと思われます。(この実験に関して言えば、実際にはブラウザの誤差はあるひとつの挙動に起因していたため、そこまで辛くなかった。後述)
色々試した結果、暫定的なベストプラクティスとして以下のルールを守るのが良さそうだという結論になりました。
flex-basisはauto(初期値)widthを0に設定する(ただしflex-direction: column+heightの時は要注意。下に追記あり)

widthを0以外にしたい場合はmin-widthをそれより小さい値で設定する

min-widthを設定すればflex-basisでもブラウザ間の差異は無くなりますが、あえてflex-basisを使うメリットも特に無さそうなのでwidthを使うのが良いかなと思ってます。
- flex-basisとmin-widthを組み合わせた例

あくまで厳密にサイズをコントロールしたい時のベストプラクティスです。(flexboxでテーブルみたいに縦を揃えたい、とか)
コンテンツのサイズが予測できたり、サイズに応じてよしなにやって欲しい時はwidth、flex-basisともにauto(必要に応じてmax-width、min-width)でも良いと思います。
幅の計算をするときに気をつけること
padding、marginの扱い
padding、marginはflex-shrink、flex-growの影響を受けないようです。
常に設定された値になる必要があるので、スペースを分配した結果が設定した値を下回る場合はスペースを再分配する必要があります。
- 左右の
padding80pxを下回るため再分配が行われる

box-sizingの影響
paddingがwidthに含まれるかどうかはbox-sizingの値によって決まります。
初期値であるcontent-boxの場合は以下のようになります。
width: autoのためコンテンツサイズ分の40px * 3を除く240pxがflex-growの値に基いて分配される

コンテンツサイズ分の
40px * 3に加え、左右のpadding40px * 3を除く120pxがflex-growの値に基いて分配される

flexアイテムの
width160px * 3とコンテナサイズ360pxの差-120pxがflex-shrinkに基いて分配される

flexアイテムの
width160px * 3に左右のpadding80px * 3を加えた720pxとコンテナサイズ360pxの差-360pxがflex-shrinkに基いて分配される

min-widthの効果
widthの設定を0以上に設定していて、その値よりコンテンツサイズが小さい場合、flex-shrinkはコンテンツサイズを下回って縮小することができなくなります。(flex-basisの場合は0に設定してもコンテンツサイズを下回るサイズにはなれないことがある。後述)
min-widthを設定することで、その値まではコンテンツサイズを下回るサイズに縮小することが出来ます。
コンテンツサイズの
160pxを下回って縮小することが出来ない(Safari、IE11は縮小する)
min-width: 0によりコンテンツサイズの160pxを下回って縮小することが出来る

ブラウザ間の差異(2016年8月28日現在)
この実験に絞って言えばブラウザ間で結果に差異が出る原因は、flex-basisがコンテンツサイズを保証するかどうか、ということに集約できました。
Chrome、Firefox、Edgeはコンテンツのサイズを維持。
Safari、IE11はコンテンツサイズを無視する。
コンテンツサイズを保証するというのはどういう事かというと、flex-shrinkやflex-growを適用した後に、もしflexアイテムのサイズがコンテンツサイズを下回っていた場合に、そのflexアイテム以外のflexアイテムの間でネガティブなスペースを再分配し、必ずコンテンツサイズを下回らない様にします。(それでも下回る場合はそれ以上縮小しない)
- 再分配してもコンテンツサイズを下回るのでそれ以上縮小しない例

どちらが仕様的に正しいのかはわかりませんが、IEを除くとコンテンツサイズを無視するのはSafariだけなのでChrome、Firefox、Edgeの動作がより最新の仕様に沿っているのかもしれません。
現在は Safari も Chrome、Firefox、Edge と同じ動作です。
追記(2016年8月31日)heightの0指定について
flex-direction: column時にheightに0を指定すると、たとえflexアイテムがflex-growによってコンテナいっぱいに広がっていたとしても、flexアイテム内の要素からはheightが0に見えてしまうらしく、%指定が出来なくなるというデメリットがあることが分かりました。(Safariのみ)
heightの代わりにmin-heightを0にすれば大丈夫でした。
- Safariのスクショ。左:
height: 0、右:height: 100%+min-height: 0

枠線付きがflexコンテナ、濃いグレーがflexアイテム、薄いグレーがflexアイテム内のブロック要素
http://codepen.io/all-user/pen/RGbKRd
追記(2016年9月5日)flex-basis の content について
flex-content に指定できる値 content についての調査を追加しました。
結論から書くとブラウザ間の挙動がバラバラ。
今はまだ使わないほうが良さそうです。
以下、実験で分かったこと。
ショートハンドが効かない(Chrome, Firefox, Safari, IE11)
ショートハンドで指定した flex-grow 、 flex-shrink がなぜか無効になります。(Edge は有効)
flex-grow は 0 (Chrome, Firefox, Safari, IE11)、 flex-shrink は 1 (Chrome, Firefox, Safari)と解釈されているように見えます。
ロングハンドの指定は有効でした。
flex-growflex-basisにcontent
flex-growに1、2、3をショートハンドで指定

flex-basisにcontent、content、auto
flex-growに1、2、3をショートハンドで指定

flex-basisにcontent
flex-growに1、2、3をロングハンドで指定

flex-shrinkflex-basisにcontent
min-widthに0
flex-shrinkに1、2、3をショートハンドで指定

flex-basisにcontent、content、auto
min-widthに0
flex-shrinkに1、2、3をショートハンドで指定

flex-basisにcontent
min-widthに0
flex-shrinkに1、2、3をロングハンドで指定


