Flexboxで要素をレイアウトするときによく使うプロパティで、justify-content:space-between;
があります。
親要素の横幅に応じて子要素を均等に配置してくれるので、マージンの計算とか特にする必要も無いので非常に便利ですよね。
僕はよく使ってます。
でも、このjustify-content:space-between;
って、要素が1行のみの場合は非常に便利なんですが、
子要素が複数行になる場合になかなか不便だったりします。
複数行の場合にどうなってしまうのか
3列のレイアウトで、最後の行の子要素が2つの場合
4列のレイアウトで、最後の行の子要素が2つの場合
4列のレイアウトで、最後の行の子要素が3つの場合
はい。こんな感じなります。
横の位置を均等に配置してる
んだからこうなるのは当たり前ですよね。
でも、我々が求めるレイアウトは最後の列は左寄せになるようなこういうやつですよね。
CSSで頑張って配置してみる
[3列のレイアウトの場合]
この場合は、CSSで以下のように、flex要素のafter疑似要素にスタイルを指定するとOKです。
.flexContent{ display:flex; justify-content:space-between; flex-wrap: wrap; &:after{ content:""; display:block; width: 150px; height:0; } }
See the Pen jKaBmK by tomoki (@chieeeeno) on CodePen.
[4列のレイアウトの場合]
この場合は、CSSで以下のように、flex要素のafterとbeforeの疑似要素にスタイルを指定するとOKです。
order
プロパティを指定して、順番を制御してやるのがポイントです。
.flexContent{ display:flex; justify-content:space-between; flex-wrap: wrap; &:before{ content:""; display:block; width: 150px; height:0; order:1; } &:after{ content:""; display:block; width: 150px; height:0; } }
See the Pen wXPeza by tomoki (@chieeeeno) on CodePen.
[5列以上のレイアウトの場合は・・・]
残念ながらCSSのみで制御するのは難しそうです。
なので、JavaScriptを使って何とかやってみます。
JavaScriptを使って対応する方法
すっごい無理矢理ですが、以下のように実装して対応することができました。
※画面幅縮めてみたりしてください。
.flexContent{ display:flex; justify-content:space-between; flex-wrap: wrap; }
$(function(){ $('.flexContent >li').each(function(index,element){ var w = $(element).width() $('.flexContent').append('<li style="height:0; width:'+ w +'px; margin:0;"></li>') }) })
See the Pen dKZWKm by tomoki (@chieeeeno) on CodePen.
何を行っているか
表示する子要素と同じ数の高さ0pxの要素をコンテナの中に突っ込んでいます。
高さ0pxなので実際に表示はされないものの、子要素と同じ幅の要素は存在しているため、
レスポンシブなどでコンテナの幅が可変の場合でも左寄せに表示することができます。
これでどんな幅でも対応はできることができました。
が、1点だけ微妙かなと思うのは、デベロッパーツールとかでソースを見たときに無駄な空要素をが入ってしまうことですかね。。。
この辺、何かうまくやる方法があったら教えてほしいです。