CSS Grid Layoutでwidthを指定してもはみ出て困った

[DMM.com Advent Calendar 2018](https://qiita.com/advent-calendar/2018/dmm) 14日目の記事です。

オンラインサロン専用SNSの開発・運用している@Hiro2525です。

最近前述したwebアプリでCSS Grid Layoutを導入してたため、Grid Layoutの紹介を兼ねて書こうと思います。

# CSS Grid Layoutとは
コンテナと呼ばれる親要素内に、アイテムと呼ばれる子要素を自由に配置ができる機能です。
以下のようなレイアウトもできたりします。（こんなレイアウトする人いないと思いますが...）
<p class="codepen" data-height="265" data-theme-id="default" data-default-tab="css,result" data-user="h1r0-2525" data-slug-hash="PowzXPK" 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="grid">
  <span>See the Pen <a href="https://codepen.io/h1r0-2525/pen/PowzXPK">
  grid</a> by hiro (<a href="https://codepen.io/h1r0-2525">@h1r0-2525</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

詳細は下記のリンクをご覧ください
https://developer.mozilla.org/ja/docs/Web/CSS/CSS_Grid_Layout
[CSS Grid Layout を極める！（基礎編）](https://qiita.com/kura07/items/e633b35e33e43240d363)

# なぜ導入したのか
開発しているwebアプリはPC、スマートフォンのソースを分けていません。レスポンシブです。
このレスポンシブの対応を容易にするために導入した次第です。

例えば、画面の幅に合わせて自動的にカラム数を増減させたい場合は親要素に
`grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));`
と指定すると、全ての子要素が180pxより広くなることができなくなった時点でカラムが減少します。
<p class="codepen" data-height="265" data-theme-id="default" data-default-tab="css,result" data-user="h1r0-2525" data-slug-hash="qBENQeB" 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="grid auto column">
  <span>See the Pen <a href="https://codepen.io/h1r0-2525/pen/qBENQeB">
  grid auto column</a> by hiro (<a href="https://codepen.io/h1r0-2525">@h1r0-2525</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

# widthが効いてない:question::question:
ここから今回の本題です。

## 現象
実際に作ったものを見ていたとき、子要素のテキストがはみ出ていることが発覚
親要素に`width: 200px;`を指定、子要素には`width: 100%;　overflow: hidden;`を指定しているのに。。。
<p class="codepen" data-height="265" data-theme-id="default" data-default-tab="html,result" data-user="h1r0-2525" data-slug-hash="KKwMrOe" 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="KKwMrOe">
  <span>See the Pen <a href="https://codepen.io/h1r0-2525/pen/KKwMrOe">
  KKwMrOe</a> by hiro (<a href="https://codepen.io/h1r0-2525">@h1r0-2525</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## 原因
単純なことで`grid-template-columns`を指定していなかったこと(正確には少し違います)でした。
今までFlexbox使っていたため子要素を`width: 100%;`指定すればいいという考えになっていました。。。

widthだけでは効かない理由は
https://developer.mozilla.org/ja/docs/Web/CSS/CSS_Grid_Layout/Basic_Concepts_of_Grid_Layout
を読んでいてわかりました

> 暗黙的または明示的なグリッド
私たちは、列トラックを grid-template-columns プロパティで定義したグリッド例を作成しましたが、コンテンツの必要に応じてグリッドに行を作成したい場合があります。これらの行は、暗黙的なグリッド内に作成されます。明示的なグリッドは、grid-template-columns および grid-template-rows で定義された行と列から構成されます。

> 定義されたグリッドの外側に何かを配置したい場合や、コンテンツの量が多いためさらにグリッドトラックが必要な場合は、グリッドが暗黙的なグリッド内に行と列を作成します。これらのトラックは、デフォルトで自動的にサイズ変更されるため、そのサイズはグリッド内部のコンテンツが基準になります。

つまり「定義されていないトラックとして作成されたため、グリッド内部のコンテンツに合わせてサイズが自動的に変更されていた」というのが正しい原因になります。

## `grid-auto-columns`、`grid-auto-rows`を使用する
前述した通り`grid-template-columns`、`grid-template-rows`を指定して、トラックを定義することも可能ですが、`grid-auto-columns`、`grid-auto-rows`という定義されていないトラックのサイズを指定できるプロパティもあります。

個人的には`grid-auto-flow`を使用して1行もしくは１列のコンポーネントを作成して、サイズを指定したい場合はこちらを使用する方がいいかなと思います。

`grid-auto-columns`を適用した結果
<p class="codepen" data-height="265" data-theme-id="default" data-default-tab="css,result" data-user="h1r0-2525" data-slug-hash="qBENLbd" 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="qBENLbd">
  <span>See the Pen <a href="https://codepen.io/h1r0-2525/pen/qBENLbd">
  qBENLbd</a> by hiro (<a href="https://codepen.io/h1r0-2525">@h1r0-2525</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## 追記 at 2019/12/13 
ちなみに`display: grid;`を指定した直下の要素に`overflow: hidden;`を指定するだけでテキストがはみ出なくなってました。
でも、お作法的にはトラックのサイズを指定してあげる方がいいのかなと思います。

<p class="codepen" data-height="265" data-theme-id="default" data-default-tab="css,result" data-user="h1r0-2525" data-slug-hash="NWPrexY" 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="NWPrexY">
  <span>See the Pen <a href="https://codepen.io/h1r0-2525/pen/NWPrexY">
  NWPrexY</a> by hiro (<a href="https://codepen.io/h1r0-2525">@h1r0-2525</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

----追記ここまで----

# ちょっと困ったこと（2023/09/05追記あり）
Gridを使用してどうしてもできなかったことが一つだけありました。
トラックの幅が全て違うかつ可変個数のコンテンツを横一列に並べ、画面端まで来たら自動的に改行するというものです。
Flexboxでは`flex-wrap`を使用すればできましたが、Gridだとどうやるのだろうか分からずじまいです。
ご存知の方がいたら教えてください:bow:

### 追記 at 2023/09/05
色々考えたのですが、上記のように可変長の要素を描画したいといった場合はFlexboxで対応するのが正しいかと思いました。
GridはFlexboxの代わりとして使うのではなく、両者を上手く使い分けることが必要そうです。


# まとめ
今回はFlexboxからGridに変更したことで新しいトラックという概念にハマってしまいました。
まだまだ使い始めたばかりで分からないことも多いですが、それでもレスポンシブ対応がしやすくなり感動しました。

もう少し使用して知見を得ていこうと思います