space-betweenめっちゃusefulやけど。
カードUIを作りたい時に困った話。
2カラム横並びの場合
<divclass="wrap"><divclass="item item01"></div><divclass="item item02"></div></div>
.wrap{display:flex;justify-content:space-between;width:600px;margin-left:auto;margin-right:auto;}.wrap.item{/* 50%←カードが2枚なので(100/2%)。んでカード間マージンを10(5×2)pxにする */width:calc(50%-5px);height:200px;background-position:centertop;background-size:cover;background-repeat:no-repeat;}.item01{background-image:url("http://dora3.work/assets/img/illust/07_tori.jpg");}.item02{background-image:url("http://dora3.work/assets/img/illust/01_usagi_03.jpg");}
https://jsfiddle.net/380mi/gm3d5nze/
3カラム横並びの場合
<divclass="wrap"><divclass="item item01"></div><divclass="item item02"></div><divclass="item item03"></div></div>
.wrap{display:flex;justify-content:space-between;width:600px;margin-left:auto;margin-right:auto;}.wrap.item{/* 33.3%←カードが3枚なので(100/3%)。 */width:calc(33.3%-5px);height:200px;background-position:centertop;background-size:cover;background-repeat:no-repeat;}.item01{background-image:url("http://dora3.work/assets/img/illust/07_tori.jpg");}.item02{background-image:url("http://dora3.work/assets/img/illust/01_usagi_03.jpg");}.item03{background-image:url("http://dora3.work/assets/img/illust/09_ino.jpg");}
https://jsfiddle.net/380mi/9r8xhdz5/
みたいな感じで、1行の場合はカードのサイズ( .item の width )だけ
なんとかしてやればどうとでもなるけど
例えばカードの数が可変な場合
もちろん、横に無限に並べるわけにはいかんやん。
だから flex-wrap:wrap; を使って改行してやるねんよ。
flex-wrap:wrap;使ってみる
例えば、横3つで折り返す時。
<divclass="wrap"><divclass="item item01"></div><divclass="item item02"></div><divclass="item item03"></div><divclass="item item04"></div><divclass="item item05"></div><divclass="item item06"></div><divclass="item item07"></div></div>
.wrap{display:flex;justify-content:space-between;width:600px;margin-left:auto;margin-right:auto;/* 折り返す */flex-wrap:wrap;}.wrap.item{/* 3つ横に並べるので、1つあたり (100/3) = 33.3% */width:calc(33.3%-5px);height:200px;background-position:centertop;background-size:cover;background-repeat:no-repeat;}/* 4枚目以降は次のカラムなので上とのマージンを確保しとく */.wrap.item:nth-child(n+4){margin-top:10px;}.item01{background-image:url("http://dora3.work/assets/img/illust/07_tori.jpg");}.item02{background-image:url("http://dora3.work/assets/img/illust/01_usagi_03.jpg");}.item03{background-image:url("http://dora3.work/assets/img/illust/09_ino.jpg");}.item04{background-image:url("http://dora3.work/assets/img/illust/15_kani.jpg");}.item05{background-image:url("http://dora3.work/assets/img/illust/14_sisi.jpg");}.item06{background-image:url("http://dora3.work/assets/img/illust/st_doku.png");}.item07{background-image:url("http://dora3.work/assets/img/illust/st_vio.jpg");}
https://jsfiddle.net/380mi/of6kcw1j/
5枚のカードを1行3枚表示させて折り返す時、悲しい結果になる。
<divclass="wrap"><divclass="item item01"></div><divclass="item item02"></div><divclass="item item03"></div><divclass="item item04"></div><divclass="item item05"></div></div>
.wrap{display:flex;justify-content:space-between;width:600px;margin-left:auto;margin-right:auto;flex-wrap:wrap;}.wrap.item{width:calc(33.3%-5px);height:200px;background-position:centertop;background-size:cover;background-repeat:no-repeat;}.wrap.item:nth-child(n+4){margin-top:10px;}.item01{background-image:url("http://dora3.work/assets/img/illust/07_tori.jpg");}.item02{background-image:url("http://dora3.work/assets/img/illust/01_usagi_03.jpg");}.item03{background-image:url("http://dora3.work/assets/img/illust/09_ino.jpg");}.item04{background-image:url("http://dora3.work/assets/img/illust/15_kani.jpg");}.item05{background-image:url("http://dora3.work/assets/img/illust/14_sisi.jpg");}
いや、CSS的には正しい挙動やけど、絶対ちゃうやんってなる。
1行目はまぁええとして、
2行目が2枚しかカードがないのに space-between しようとしてるから
左右に均等配置されてまうねん。
だからカード要素のケツに一発疑似要素を仕込んでやるわけ。
<divclass="wrap"><divclass="item item01"></div><divclass="item item02"></div><divclass="item item03"></div><divclass="item item04"></div><divclass="item item05"></div></div>
.wrap{display:flex;justify-content:space-between;width:600px;margin-left:auto;margin-right:auto;flex-wrap:wrap;}.wrap.item{width:calc(33.3%-5px);height:200px;background-position:centertop;background-size:cover;background-repeat:no-repeat;}/* 同じサイズの疑似要素を仕込む */.wrap::after{content:"";display:block;width:calc(33.3%-5px);}.wrap.item:nth-child(n+4){margin-top:10px;}.item01{background-image:url("http://dora3.work/assets/img/illust/07_tori.jpg");}.item02{background-image:url("http://dora3.work/assets/img/illust/01_usagi_03.jpg");}.item03{background-image:url("http://dora3.work/assets/img/illust/09_ino.jpg");}.item04{background-image:url("http://dora3.work/assets/img/illust/15_kani.jpg");}.item05{background-image:url("http://dora3.work/assets/img/illust/14_sisi.jpg");}
つまり不足分の要素を入れてやればおkってこと。
https://jsfiddle.net/380mi/av7gchsr/
2つ要素が空いてもうた場合
でも結局、空き個数分埋めてやればおkっていう原則に戻ると
なんかしらで空き要素を埋めてやったらいいって事。
ここでflexboxの真髄、order を使うねん。
具体的には、.warpにafterに次いでさらにbeforeを追加して
んでそのbeforeをケツにもって来たったらええわけ。
<divclass="wrap"><divclass="item item01"></div><divclass="item item02"></div><divclass="item item03"></div><divclass="item item04"></div><divclass="item item05"></div></div>
.wrap{display:flex;justify-content:space-between;width:600px;margin-left:auto;margin-right:auto;flex-wrap:wrap;}.wrap.item{width:calc(25%-5px);height:200px;background-position:centertop;background-size:cover;background-repeat:no-repeat;}.wrap::after{content:"";display:block;width:calc(25%-5px);}/* before疑似要素を追加して末尾に追加 */.wrap::before{order:1;content:"";display:block;width:calc(25%-5px);}.wrap.item:nth-child(n+5){margin-top:10px;}.item01{background-image:url("http://dora3.work/assets/img/illust/07_tori.jpg");}.item02{background-image:url("http://dora3.work/assets/img/illust/01_usagi_03.jpg");}.item03{background-image:url("http://dora3.work/assets/img/illust/09_ino.jpg");}.item04{background-image:url("http://dora3.work/assets/img/illust/15_kani.jpg");}.item05{background-image:url("http://dora3.work/assets/img/illust/14_sisi.jpg");}.item06{background-image:url("http://dora3.work/assets/img/illust/st_doku.png");}
5カラム並んだ時どうすんねん
というか、そもそも横に5つ並ぶデザインってユーザビリティ的にどないやねん!って感じもするけど…
そんなに一気に視認させられても感ある。
まぁそれは置いておいて、仰せのままにコーディングするなら
5カラム均等配置もできなあかんし。
普通にカードのサイズを5カラム( 20%(100/5) )にすると
なんかもうそれはそれで逆にいい感じになる。
でも、BAD!なので
さっきの原則に戻って、「空いてる分どうにかしてやる」という考え方に達すると
3個あいてるやんってなるけど
擬似要素はbefore,afterしかないから、そいつらで追加できんのは2つまで…
となると、もうDOMを追加するしかない…
<divclass="wrap"><divclass="item item01"></div><divclass="item item02"></div><divclass="item item03"></div><divclass="item item04"></div><divclass="item item05"></div><divclass="item item06"></div><divclass="item item07"></div><divclass="item empty"></div><divclass="item empty"></div><divclass="item empty"></div></div>
.wrap{display:flex;justify-content:space-between;width:600px;margin-left:auto;margin-right:auto;flex-wrap:wrap;}.wrap.item{width:calc(20%-5px);height:200px;background-position:centertop;background-size:cover;background-repeat:no-repeat;}/* 空要素 */.wrap.item.empty{display:block;width:calc(20%-5px);}.wrap.item:nth-child(n+6){margin-top:10px;}.item01{background-image:url("http://dora3.work/assets/img/illust/07_tori.jpg");}.item02{background-image:url("http://dora3.work/assets/img/illust/01_usagi_03.jpg");}.item03{background-image:url("http://dora3.work/assets/img/illust/09_ino.jpg");}.item04{background-image:url("http://dora3.work/assets/img/illust/15_kani.jpg");}.item05{background-image:url("http://dora3.work/assets/img/illust/14_sisi.jpg");}.item06{background-image:url("http://dora3.work/assets/img/illust/st_doku.png");}.item07{background-image:url("http://dora3.work/assets/img/illust/st_hen.png");}
https://jsfiddle.net/380mi/4k7va396/
というか、サンプルみたいに .item で表示させる内容の中(.itemのchild)がなんも無いって事
実務ではあんまりなさそうやし、empty疑似クラスを使ってやった方が
わざわざ .empty とかクラスつけんでええからそっちのが楽そう。
こんな感じ↓
<divclass="wrap"><divclass="item item01"><span></span></div><divclass="item item02"><span></span></div><divclass="item item03"><span></span></div><divclass="item item04"><span></span></div><divclass="item item05"><span></span></div><divclass="item item06"><span></span></div><divclass="item item07"><span></span></div><divclass="item"></div><divclass="item"></div><divclass="item"></div></div>
.wrap{display:flex;justify-content:space-between;width:600px;margin-left:auto;margin-right:auto;flex-wrap:wrap;}.wrap.item{width:calc(20%-5px);height:200px;background-position:centertop;background-size:cover;background-repeat:no-repeat;}/* empty疑似クラスで対応に変更した */.wrap.item:empty{display:block;width:calc(20%-5px);}.wrap.item:nth-child(n+6){margin-top:10px;}.item01{background-image:url("http://dora3.work/assets/img/illust/07_tori.jpg");}.item02{background-image:url("http://dora3.work/assets/img/illust/01_usagi_03.jpg");}.item03{background-image:url("http://dora3.work/assets/img/illust/09_ino.jpg");}.item04{background-image:url("http://dora3.work/assets/img/illust/15_kani.jpg");}.item05{background-image:url("http://dora3.work/assets/img/illust/14_sisi.jpg");}.item06{background-image:url("http://dora3.work/assets/img/illust/st_doku.png");}.item07{background-image:url("http://dora3.work/assets/img/illust/st_hen.png");}
https://jsfiddle.net/380mi/b1q2zh5u/
jsで力技できんちゃん?力こそパワー
ページ内に「ここは3カラムで改行」、「ここは5カラムで改行」みたいに複数あった場合、
わざわざやるの面倒くさいので、もうjsでごりごりやっちゃう。
jQueryで書いてるけど。
<divclass="wrap js-jcBetween"data-column="5"><divclass="item item01"><span></span></div><divclass="item item02"><span></span></div><divclass="item item03"><span></span></div><divclass="item item04"><span></span></div><divclass="item item05"><span></span></div><divclass="item item06"><span></span></div><divclass="item item07"><span></span></div></div>
.wrap{display:flex;justify-content:space-between;width:600px;margin-left:auto;margin-right:auto;flex-wrap:wrap;}.wrap.item{height:200px;background-position:centertop;background-size:cover;background-repeat:no-repeat;}.wrap.item:empty{display:block;}.wrap.item.js-marginTop{margin-top:10px;}.item01{background-image:url("http://dora3.work/assets/img/illust/07_tori.jpg");}.item02{background-image:url("http://dora3.work/assets/img/illust/01_usagi_03.jpg");}.item03{background-image:url("http://dora3.work/assets/img/illust/09_ino.jpg");}.item04{background-image:url("http://dora3.work/assets/img/illust/15_kani.jpg");}.item05{background-image:url("http://dora3.work/assets/img/illust/14_sisi.jpg");}.item06{background-image:url("http://dora3.work/assets/img/illust/st_doku.png");}.item07{background-image:url("http://dora3.work/assets/img/illust/st_hen.png");}
$(function(){$('.js-jcBetween').each(function(){// 何カラムか取得letcolumn=$(this).attr('data-column');// 親のサイズletwrapWidth=$(this).width();// flexitem(カード) 一個あたりのサイズletitemWidth=(+wrapWidth/+column)-5;// 追加するアイテムの個数letemptyItemCount=+$(this).children('.item').length-+column;// 空の要素追加varemptyElement='';for(vari=0,l=emptyItemCount;i<=l;i++){emptyElement+='<div class="item"></div>';}$(this).append(emptyElement);// カードにサイズを付加$(this).children('.item').width(itemWidth);// 2行目以降にmargin-topを付加$(this).children('.item:gt('+(+column-1)+')').addClass('js-marginTop');});});
https://jsfiddle.net/380mi/va0bpsk3/
ただこれやと、スマホの時も5カラムになっちゃうから、その辺スマホを分岐してカラムを決定する方がいいかも。