cssで要素を横並びにする方法まとめ


## 基本となるhtml
```html
<div class="boxContainer">
  <div class="box">BOX1</div>
  <div class="box">BOX2</div>
  <div class="box">BOX3</div>
  <div class="box">BOX4</div>
  <div class="box">BOX5</div>
</div>
```

cssのみ方法を変えてそれぞれの方法にどのようなメリット・デメリットがあるか見ていく。

## float
```css
.box{
  float: left;
}

.boxContainer{
  overflow: hidden;
}
```

### メリット
- 子要素の左右の順番を変えたい場合にcssのみで調整できる（ただし、左右のみなので大々的な修正はしづらい）
- 子要素の内容により高さが変わる場合は上揃えになる（この点では、子要素の高さの増減に対応しやすい）

### デメリット
- 子要素は文字通りfloat（浮いた）状態になり親要素の高さが0になってしまう
- 子要素の内容は基本上揃えになる（vertical-alignが使用できない）
- 親要素の幅を指定しないとレイアウトが崩れる場合がある

#### 親要素の高さ0の解消方法
- 親要素に`overflow:hidden`を設定する（ただし親要素からはみ出る要素が隠れる）
- floatした後にくる子要素に`clear:both`を設定する
- 親要素自体をfloatさせる
- 親要素に以下のようにclearfixを設定する

```css
.clearfix:after {
  content:" ";
  display:block;
  clear:both;
}
```
IE7以下をサポートしなければかなりスッキリする。
簡単なのは`overflow:hidden`とclearfix。

## inline-block
```css
.box{
  display: inline-block;
  font-size: 16px;
}

.boxContainer{
  font-size: 0;
}
```

### メリット
- 子要素同士の高さが異なり、親要素の幅が狭まった場合でもレイアウトが崩れることがない

### デメリット
- 子要素の間に改行による隙間ができてしまう
- 子要素同士の並びをcssのみで調整することはできない
- 子要素の内容は基本上揃えになる（vertical-alignが使用できない）

#### 改行による隙間の解消方法
- 親要素のfont-sizeを0にして子要素でfont-sizeを指定する
- 子要素の改行を取り払って以下のように一行で記述する

```
<div class="box">BOX1</div><div class="box">BOX2</div><div class="box">BOX3</div>
```

- 改行を以下のようにコメントアウトする

```
<div class="box">BOX1</div><!-- 
--><div class="box">BOX2</div><!-- 
--><div class="box">BOX3</div>
```

- 子要素の閉じタグを以下のように次の子要素の前に持ってくる

```
<div class="box">BOX1
</div><div class="box">BOX2
</div><div class="box">BOX3</div>
```

スマートなのは親要素のfont-sizeを0にする方法。

## table-cell
```css
.box{
  display: table-cell;
  vertical-align: middle;
}

.boxContainer{
  width: 100%;
  display: table;
  table-layout: fixed;
}
```

### メリット
- 子要素の幅を設定しなくても親要素の幅を指定するだけで自動的に子要素の幅が割り付けられる
- 親要素に`table-layout:fixed`を指定することで、子要素の幅が内容によって増減しても子要素の幅は均等に割り付けられる
- 子要素の内容の高さを揃えるのにvertical-alignを設定できる

### デメリット
- marginによる子要素同士の調整ができない（paddingはできる）（border-spacingによる調整もできるが、子要素全てで均等にしかできない）
- 親要素の幅を変更してのレイアウト調整に対応しづらい（レスポンシブ対応など）

## flexbox
```css
.boxContainer{
  display: flex;
}
```
横並びにするだけなら親要素にこれ一行だけでOK。
flex-directionの初期値がrowなため。

## メリット
- 親要素にjustify-contentを指定することで子要素全体の水平位置を設定できる
- 親要素にalign-itemsを指定することで子要素全体の垂直位置を設定できる
- 親要素にflex-directionを指定することで子要素全体の並びを設定できる
- 子要素にflexを指定することで子要素の幅をリキッドに設定できる

## デメリット
- 対応ブラウザがまだ芳しくない

### 対応ブラウザ
http://caniuse.com/#search=flex

IE9は未対応。IE10は`display:-ms-flexbox`
また、IE11では`flex:1`ではなく`flex-grow：1`としなければならない。
Safari8 未満は`display: -webkit-flex`
iOS9 未満は`display: -webkit-flex`
Android 4.3 未満は`display: -webkit-box`

### justify-content
|値|説明|
|:--|:--|
|center|子要素全体を左右中央揃えに|
|flex-start|子要素全体を左揃えに|
|flex-end|子要素全体を右揃えに|
|space-between|子要素全体は利用可能な領域いっぱいに広がり、最初の子要素が左端に、最後の子要素が右端に移動し、その間の要素は等間隔に並べられる|

### align-items
|値|説明|
|:--|:--|
|center|子要素全体を上下中央揃えに|
|flex-start|子要素全体を上揃えに|
|flex-end|子要素全体を下揃えに|

### flex
flex-grow、flex-shrink、flex-basisのショートハンド。
全ての子要素を`flex:1`にすれば、子要素の幅を利用可能な領域いっぱいかつ同じ幅にする。
その中の1子要素を`flex:2`にすれば、その子要素のみ他の子要素の2倍の幅になる。

### flex-direction
|値|説明|
|:--|:--|
|row|子要素全体の並びを横並びにする|
|column|子要素全体の並びを縦並びにする|

## まとめ
- ブラウザ対応に問題がなければflexbox
- レイアウト全体など子要素の内容が大きく増減しそうな場合はfloat
- 子要素の左右の入れ替えが発生しそうな場合はfloat
- ナビゲーションなど子要素の内容が小さく増減しなさそうな場合はinline-block
- vertical-alignが必要になりそうな場合はtable-cell

## 参考URL
[display:table-cell;を安易に使うべきでない理由いろいろ](http://qiita.com/sawadays0118/items/4c329fd05cdff14ffebc)
[これからのCSSレイアウトはFlexboxで決まり！ | Webクリエイターボックス](http://www.webcreatorbox.com/tech/flexbox/)