【忘備録】display:flexで複数カラムレイアウトを自由に実装する

#display:flexで複数カラムのレイアウトを自由に実装する

``display:flex`` はデフォルトでは``display:table-cell``と同じ様に折り返しが利きませんが、``flex-wrap: wrap``を指定する事ではみ出した分は折り返すようになります。(イメージとしては``float:left``でコーディングするのと同じイメージです)
``justify-content: center``と``align-items: center``を用いて縦横のセンタリングを適用が適用されるのでマークアップを変更することなく自由にレイアウトを実装する事が可能です。
使いどころとしては商品一覧ページで特定のアイテムだけ大きく見せたい場合などがあるかと思います。

##display:flexを使った実装サンプル 

<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="result" data-user="YusukeIkeda" data-slug-hash="qBOLjpo" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="qBOLjpo">
  <span>See the Pen <a href="https://codepen.io/YusukeIkeda/pen/qBOLjpo">
  qBOLjpo</a> by YusukeIkeda (<a href="https://codepen.io/YusukeIkeda">@YusukeIkeda</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

```html:HTML
<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="UTF-8">
	<title>display:flex</title>
	<link rel="stylesheet" href="style.css">
</head>
<body>
	<div class="container">
	<ul class="flex">
		<li class="flex-item col2">ITEM 1</li>
		<li class="flex-item col2">ITEM 2</li>
		<li class="flex-item col1">ITEM 3</li>
		<li class="flex-item col2">ITEM 4</li>
		<li class="flex-item col2">ITEM 5</li>
		<li class="flex-item col1">ITEM 6</li>
		<li class="flex-item col2">ITEM 7</li>
		<li class="flex-item col2">ITEM 8</li>
	</ul>
</div>
</body>
</html>
```

```css:style.css
*{
	padding: 0;
	margin: 0;
}
li{
	list-style: none;
}
.container{
	width: 600px;
	margin: auto;
}
.flex{
	display: flex;
	flex-wrap: wrap;
	justify-content: space-between;
}
.flex-item{
	display: flex; /* 子要素のテキストを縦横中央揃えにする */
	justify-content: center;
	align-items: center;
	height: 100px;
	margin-bottom: 10px;
	border: solid #000 2px;
	color: #fff;
}
.flex-item:nth-child(3n){
	background: #0080FF;
}
.flex-item:nth-child(3n-1),
.flex-item:nth-child(3n-2){
	background: #FF80C0;
}
.col1{
	flex-basis: 100%;
}
.col2{
	flex-basis: calc(50% - 10px);
}
```


#参考1：floatで実装した場合

最近はあまり見かけないけどfloatを使用してもコードの量はあまり変わらず実装する事はできます。
ただしfloatで実装した場合は子要素のテキストを縦に中央揃えさせたい場合、下記サンプルのようにdisplay:tableを指定するなどの工夫が必要になってきます。
また、スマホページに最適化させたい場合、デバイスの幅によってレイアウト崩れが起きないように幅やマージンを調整する必要があるので現在はあまり良い選択肢ではありません。

##floatを使った実装サンプル 

<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="result" data-user="YusukeIkeda" data-slug-hash="oNjJeQg" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="oNjJeQg">
  <span>See the Pen <a href="https://codepen.io/YusukeIkeda/pen/oNjJeQg">
  oNjJeQg</a> by YusukeIkeda (<a href="https://codepen.io/YusukeIkeda">@YusukeIkeda</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

```html:HTML
<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="UTF-8">
	<title>float</title>
	<link rel="stylesheet" href="style.css">
	</style>
</head>
<body>
	<div class="container clearfix">
	<ul class="list">
		<li class="list-item col2"><p class="text">ITEM 1</p></li>
		<li class="list-item col2"><p class="text">ITEM 2</p></li>
		<li class="list-item col1"><p class="text">ITEM 3</p></li>
		<li class="list-item col2"><p class="text">ITEM 4</p></li>
		<li class="list-item col2"><p class="text">ITEM 5</p></li>
		<li class="list-item col1"><p class="text">ITEM 6</p></li>
		<li class="list-item col2"><p class="text">ITEM 7</p></li>
		<li class="list-item col2"><p class="text">ITEM 8</p></li>
	</ul>
</div>
</body>
</html>

```

```css:CSS
*{
	padding: 0;
	margin: 0;
}
li{
	list-style: none;
}
.clearfix:after{
	content: '';
	display: block;
	clear: both;
}
.container{
	width: 600px;
	margin: auto;
}
.list-item{
	display: table;
	float: left;
	text-align: center;
	margin-bottom: 10px;
	border: solid #000 2px;
	color: #fff;
}
.list-item:nth-child(3n-1){
	float: right;
}
.list-item:nth-child(3n){
	background: #0080FF;
}
.list-item:nth-child(3n-1),
.list-item:nth-child(3n-2){
	background: #FF80C0;
}
.text{
	display: table-cell;
	vertical-align: middle;
	height: 100px;
}
.col1{
	width: 100%;
	box-sizing: border-box;
}
.col2{
	width: calc(50% - 10px);
}
```

#参考2：display:gridで実装した場合
まだ実務で使ったことは無いですが、display:gridを使用すると様々なレイアウトがCSSだけで実現できるようになります。
##display:gridを使った実装サンプル

<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="result" data-user="YusukeIkeda" data-slug-hash="yLYZNLq" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="yLYZNLq">
  <span>See the Pen <a href="https://codepen.io/YusukeIkeda/pen/yLYZNLq">
  yLYZNLq</a> by YusukeIkeda (<a href="https://codepen.io/YusukeIkeda">@YusukeIkeda</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>




```html:HTML
<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="UTF-8">
	<title>grid</title>
	<link rel="stylesheet" href="style.css">
	</style>
</head>
<body>
	<div class="container">
	<ul class="grid">
		<li class="grid-item box1">ITEM 1</li>
		<li class="grid-item box2">ITEM 2</li>
		<li class="grid-item box3">ITEM 3</li>
		<li class="grid-item box4">ITEM 4</li>
		<li class="grid-item box5">ITEM 5</li>
		<li class="grid-item box6">ITEM 6</li>
	</ul>
</div>
</body>
</html>
```

```css:CSS
*{
	padding: 0;
	margin: 0;
}
li{
	list-style: none;
}
.container{
	width: 600px;
	margin: auto;
}
.grid{
	display: grid;
	grid-template-columns: 1fr 1fr;
	column-gap: 10px;
	row-gap: 10px;
	text-align: center;
}
.grid-item{
	display: grid;
    align-items: center;
	height: 100px;
	color: #fff;
	border: solid #000 2px;
}
.grid-item:nth-child(3n){
	background: #0080FF;
}
.grid-item:nth-child(3n-1),
.grid-item:nth-child(3n-2){
	background: #FF80C0;
}
.box3, .box6{
	grid-column-start: 1;
	grid-column-end: 3;
}
```

#まとめ
display:flexをうまく使えれば今まではHTMLの構成を組み替える必要があったレイアウト変更もCSSだけで対応可能になりそうです。同じレイアウトを実現するにもいくつもの実装方法がある事を知っておくと様々なケースに対応することが出来ます。