cssのflexを使って、3列以上の幅が均等な要素を横並びにして左右にぴったりくっつけたい場合、以下のように記述すればOK。
1 2 3 4 5 |
<div class="box"> <div class="item"></div> <div class="item"></div> <div class="item"></div> </div> |
1 2 3 4 |
.box { display: flex; justify-content: space-between; } |
2行以上にする場合はflex-wrap:wrap;を追加。
1 2 3 4 5 |
.box { display: flex; justify-content: space-between; flex-wrap: wrap; } |
しかしこのままだと、要素の数が決まっていない場合で、例えば5個とかの場合に問題が発生する。こんな感じになっちゃう
3列ならまだ「こういうもんなの…ちょっとおかしい気もするけど…まぁいいか」で済ませられることもあるけど、4列・5列となるにつれどんどん気持ち悪くなっていく。
これをシンプルに解決する方法がこちら。
解決方法
結論からいうと、こういう場合はjustify-content: space-between;は使いません。
なんか疑似要素やjQueryを使って空の要素を補完するとかいう方法を見かけましたが、そんな無理してやらなくても、同じようなことはできます。
パターンA:親要素を左にちょっとずらす
以下のように、子要素は均等にmargin-leftをつけておき、親要素自体を左にちょっとずらす
1 2 3 4 5 6 7 8 |
.box { display: flex; flex-wrap: wrap; margin-left: -20px; } .item { margin-left: 20px; } |
書き方はスッキリしていて、いいと思います。
ただ、幅を%で指定したいときや、親要素を左にずらすスペースがない場合ややこしいので、僕は次のパターンBを推します。
パターンB:一番左の子要素だけmargin-left:0;にする
疑似要素 :nth-child() を利用して、一番左の子要素だけmargin-left:0;にしちゃいましょう。
また、レスポンシブの場合は画面幅によって並べる数が違うと思うので、メディアクエリを使うとスッキリします。
1 2 3 4 5 6 7 8 9 10 11 12 |
.box { display: flex; flex-wrap: wrap; } .item { margin-left: 20px; } @media screen and (min-width: 751px){ .item:nth-child(3n+1) { margin-left: 0; } } |
さらにいうと、スマホでは2列!という場合、justify-content:spcae-between;のほうが幅を気にせずに済むので、効率がいいです。
例:1000px以上は4列、751px~1000pxでは3列、750px以下(スマホ)では2列にするよ!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
.box { display: flex; flex-wrap: wrap; } .item { margin-left: 20px; } @media screen and (min-width: 1001px){ .item:nth-child(4n+1) { margin-left: 0; } } @media screen and (min-width: 751px){ .item:nth-child(3n+1) { margin-left: 0; } } @media screen and (max-width: 750px){ .box { justify-content: space-between; } .item { margin-left: 0; } } |
以上、現場からでした。