【CSS】display:flexでmax-widthが効かない時の対処法。calcやflex-basisの活用

フレックスコンテナの中の子要素にmax-widthを適用しても効かず、幅が最少になってしまう時の対処法。


##flexコンテナとmax-width
flexコンテナの中の要素（子要素や孫要素など）に`max-width`を適用することはできない。

自動で最少の幅となってしまう。`width`を指定することはできる。

また、対象要素が孫要素の場合も`max-width`が適用されない。

<br>
##適用できない事例
子要素のアイテム１とアイテム２に`max-width: 200px`を記述しているが適用されない。

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/a232ff47-8b87-86eb-22ee-9476ccb94af2.png)|
|:--|


```html:.html
<p>▼子要素にmax-widthを設定</p>
<div class="flex-wrapper">
  <div class="flex-item1">
    <p>アイテム１</p>
  </div>
  <div class="flex-item2">
    <p>アイテム2</p>
  </div>
</div>
```

```scss:.scss
.flex{
  &-wrapper{
    display: flex;
    max-width: 800px;
    color:white;
  }
  &-item{
    &1{
      background: red;
      max-width: 400px;
    }
    &2{
      background: blue;
      max-width: 400px;
    }
  }
}
```

<br>
**▼widthは適用される**
max-widthを`width`に変更すれば適用される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/4f218430-0a6b-7206-d669-deb8ef38027b.png)



<br>
##対処法
方法はいくつかある。一番わかりやすいのはwidthの指定で`%`を使う方法。

その他に`flex-basis`を使う方法もある。


###1. 収める個数が決まっている場合 calc(x%)
長さ指定ではなく、1行に2個や3個など収めたい要素の個数が決まっている場合はwidthを`%`（または`calc(X% - Ypx)`）で表せば長さが調整できるようになる。

![percent.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/2deacdc6-40b5-6176-e9af-8b4dc57214d7.gif)

```scss:.scss
.flex-y{
  &-wrapper{
    display: flex;
    color:white;
    max-width: 800px;
  }
  &-item{
    &1{
      background: red;
      width: 50%;![percent.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/98ef2107-d1f2-a8c5-b6ec-297cbb867546.gif)

    }
    &2{
      background: blue;
      width: 50%;
    }
  }
}
```

<br>
###calc(X% - Ypx)の例
calc(X% - Ypx)を使えば隙間を空けて均等に配置することができる。

親要素に`justify-content: space-between;` (値はspace-aroundやspace-evenlyなどもある)を設定し、子要素に`width: calc(50% - 20px);`を設定した場合は以下となる。

![space-between.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/5198ebfc-8d2b-7e56-18d9-cced47d2e7d6.gif)


```scss:.scss
.flex-y{
  &-wrapper{
    display: flex;
    justify-content: space-between;
    color:white;
    max-width: 800px;
  }
  &-item{
    &1{
      background: red;
      width: calc(50% - 20px);
    }
    &2{
      background: blue;
      width: calc(50% - 20px);
    }
  }
}
```





<br>
###2. 子要素の場合(flex-basis)
max-widthを`flex-basis`に変更する。
flex-basisはフレックスコンテナ内の要素の基本となる幅を指定するプロパティ。

画面幅を超える場合は収まるように自動調整される。

![flex-basis.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/d2820c00-308b-8616-9c9d-f70355189d7a.gif)


```scss:.scss
.flex-x{
  &-wrapper{
    display: flex;
    color:white;
  }
  &-item{
    &1{
      background: red;
      flex-basis: 400px;
    }
    &2{
      background: blue;
      flex-basis: 400px;
    }
  }
}
```



<br>
###3. 孫要素の場合
孫要素が`display: inline-box`の場合もmax-widthが適用されない。

この場合は、子要素に`flex-basis: 最大幅`を適用し、孫要素に`width: 100%;`を指定する。

こうすることで、孫要素が子要素いっぱいに広がった状態になり、画面幅に合わせて子要素が伸縮する。(max-widthと同じ動きになる)

![flex-basis.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/64cb9918-19d8-9b7d-7692-0060b292490e.gif)


```scss:.scss
.flex{
  &-wrapper{
    display: flex;
    color:white;
  }
  &-item{
    &1{
      background: red;
      flex-basis: 400px; //子要素
    }
  }
  &-text{
    &1{
      display: inline-block;
      background: gold;
      width: 100%;  //孫要素
    }
  }
}
```

```html:.html
<p>▼子要素にflex-basis、孫要素にwidth100%を設定</p>
<div class="flex-wrapper">
  <div class="flex-item1">
    <span class="flex-text1">アイテム１</span>
  </div>
</div>
```