【Flexbox】display:flex; justfy-content:space-betweenで左詰めしたい。

#space-betweenめっちゃusefulやけど。
カードUIを作りたい時に困った話。

## 2カラム横並びの場合
![f05f5244f7bedf60d798047c59574ff1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542762/6c3395ee-d5ee-b90b-6bc7-6e2efbbaeb0f.png)

```html
<div class="wrap">
    <div class="item item01"></div>
    <div class="item item02"></div>
</div>
```
```css
.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: center top;
    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カラム横並びの場合
![f3464c8c65578370355d3880f4b10267.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542762/d22a4e8d-f760-e2e4-a733-33e5583ef28b.png)

```html
<div class="wrap">
    <div class="item item01"></div>
    <div class="item item02"></div>
    <div class="item item03"></div>
</div>
```
```css
.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: center top;
    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つで折り返す時。
こんな感じで。
![495a47f6ed32d36f781900f5920b6478.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542762/9f53290f-29b6-d810-9e9e-9eeeef0bb43d.png)

```html
<div class="wrap">
    <div class="item item01"></div>
    <div class="item item02"></div>
    <div class="item item03"></div>
    <div class="item item04"></div>
    <div class="item item05"></div>
    <div class="item item06"></div>
    <div class="item item07"></div>
</div>
```

```css
.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: center top;
    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枚表示させて折り返す時、悲しい結果になる。
![7c3dabee0cc5b607cb618ba79ab63745.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542762/1d34e9b2-080e-56c2-0a35-38e590f36241.png)
こんな感じで。

```html
<div class="wrap">
    <div class="item item01"></div>
    <div class="item item02"></div>
    <div class="item item03"></div>
    <div class="item item04"></div>
    <div class="item item05"></div>
</div>
```
```css
.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: center top;
    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 しようとしてるから
左右に均等配置されてまうねん。

だからカード要素のケツに一発疑似要素を仕込んでやるわけ。

```html
<div class="wrap">
    <div class="item item01"></div>
    <div class="item item02"></div>
    <div class="item item03"></div>
    <div class="item item04"></div>
    <div class="item item05"></div>
</div>
```

```css
.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: center top;
    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");}
```

するとハッピーな結果に。
![02e1b1ac1e995763451816fe434d8a16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542762/e31d3d42-9e63-df86-1423-d5643c8d25de.png)

つまり不足分の要素を入れてやればおｋってこと。


https://jsfiddle.net/380mi/av7gchsr/

## 2つ要素が空いてもうた場合
![29729644d849338c6beb6e260bf06e32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542762/e0912668-f4fb-a2ae-fe7f-c2c554eda6c4.png)
悲しい結果に。

でも結局、空き個数分埋めてやればおｋっていう原則に戻ると
なんかしらで空き要素を埋めてやったらいいって事。

ここでflexboxの真髄、order を使うねん。
具体的には、.warpにafterに次いでさらにbeforeを追加して
んでそのbeforeをケツにもって来たったらええわけ。

```html
<div class="wrap">
    <div class="item item01"></div>
    <div class="item item02"></div>
    <div class="item item03"></div>
    <div class="item item04"></div>
    <div class="item item05"></div>
</div>
```

```css
.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: center top;
    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");}
```
![2ed49cf661e762c52b22c27f0cac604d.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542762/a8e39a4e-eed7-f8a5-15d9-d20ae0517477.png)
ハッピーな結果に。

## 5カラム並んだ時どうすんねん
というか、そもそも横に5つ並ぶデザインってユーザビリティ的にどないやねん！って感じもするけど…
そんなに一気に視認させられても感ある。

まぁそれは置いておいて、仰せのままにコーディングするなら
5カラム均等配置もできなあかんし。

普通にカードのサイズを5カラム( 20%(100/5) )にすると
なんかもうそれはそれで逆にいい感じになる。
![ac495ad9e6865648b48a671cfedca71c.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542762/e35a1ce2-68c4-f4ee-1774-1bc528c42ff9.png)

でも、BAD！なので
さっきの原則に戻って、「空いてる分どうにかしてやる」という考え方に達すると
3個あいてるやんってなるけど
擬似要素はbefore,afterしかないから、そいつらで追加できんのは2つまで…
となると、もうDOMを追加するしかない…
![d50205fc863845c99815c604761574df.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542762/82fab35f-3ffb-ee41-73cc-2877e448db03.png)

```html
<div class="wrap">
    <div class="item item01"></div>
    <div class="item item02"></div>
    <div class="item item03"></div>
    <div class="item item04"></div>
    <div class="item item05"></div>
    <div class="item item06"></div>
    <div class="item item07"></div>
    <div class="item empty"></div>
    <div class="item empty"></div>
    <div class="item empty"></div>
</div>
```

```css
.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: center top;
    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 とかクラスつけんでええからそっちのが楽そう。

こんな感じ↓

```html
<div class="wrap">
    <div class="item item01"><span></span></div>
    <div class="item item02"><span></span></div>
    <div class="item item03"><span></span></div>
    <div class="item item04"><span></span></div>
    <div class="item item05"><span></span></div>
    <div class="item item06"><span></span></div>
    <div class="item item07"><span></span></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
</div>
```

```css
.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: center top;
    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で書いてるけど。

```html
<div class="wrap js-jcBetween" data-column="5">
    <div class="item item01"><span></span></div>
    <div class="item item02"><span></span></div>
    <div class="item item03"><span></span></div>
    <div class="item item04"><span></span></div>
    <div class="item item05"><span></span></div>
    <div class="item item06"><span></span></div>
    <div class="item item07"><span></span></div>
</div>
```

```css
.wrap{
    display: flex;
    justify-content: space-between;
    width: 600px;
    margin-left: auto;
    margin-right: auto;
    flex-wrap:wrap;
}
.wrap .item{
    height: 200px;
    background-position: center top;
    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");}
```

```javascript
$(function(){
	$('.js-jcBetween').each(function(){
    	// 何カラムか取得
    	let column = $(this).attr('data-column');
		// 親のサイズ
		let wrapWidth = $(this).width();
        // flexitem（カード） 一個あたりのサイズ
        let itemWidth = (+wrapWidth / +column) - 5;
		// 追加するアイテムの個数
		let emptyItemCount = +$(this).children('.item').length - +column;
        // 空の要素追加
        var emptyElement = '';
        for ( var i = 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カラムになっちゃうから、その辺スマホを分岐してカラムを決定する方がいいかも。