CSS Gridを使うときにSubgridを使うと楽＆事故りづらい

## これは何

- CSS Gridを使う際のTipsです
- イベント「3000文字Tips - 知ると便利なTipsをみんなへ届けよう」への投稿記事でもあります

https://qiita.com/official-events/d523df99d6479293ffa7

## リポジトリとGitHub Pages

この記事を書くために書いたコードは公開しています。

https://github.com/xrxoxcxox/qiita-css-subgrid/tree/main

GitHub PagesにはSubgridの対応状況の関係でGitHub PagesにはFirefoxからアクセスしてください。

https://xrxoxcxox.github.io/qiita-css-subgrid/

## Subgridを使わないと

CSS Grid、便利ですよね。

けど`display: grid`を適用しても直下の要素しかグリッドアイテムとして認識されません。

もちろんgridを入れ子にすれば階層が深くなっても問題表示上問題はありませんが、何回も`grid-template-columns`や`grid-template-rows`を書くはめになります。

以下の例では、青いエリアはdivが入れ子になっていて、もともとのグリッドに合わせるために手入力で`grid-template-columns`や`grid-template-rows`を指定しなおしています。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/8c8b321c-27fd-adb1-6a37-3071e5b83e5d.png" width="400" alt="" />

```html
<div class="grid">
  <h1 class="headline">Subgrid不使用</h1>
  <div class="grid-item">1</div>
  <div class="grid-item">2</div>
  <div class="grid-item">3</div>
  <div class="grid-item">4</div>
  <div class="grid-item">5</div>
  <div class="grid-item">6</div>
  <div class="grid-item">7</div>
  <div class="grid-item">8</div>
  <div class="grid-item">9</div>
  <div class="grid-item">10</div>
  <div class="grid-item">11</div>
  <div class="non-subgrid">
    <div class="nested-grid-item">12</div>
    <div class="nested-grid-item">13</div>
    <div class="nested-grid-item">14</div>
    <div class="nested-grid-item">15</div>
  </div>
  <div class="grid-item">16</div>
  <div class="grid-item">17</div>
  <div class="grid-item">18</div>
  <div class="grid-item">19</div>
  <div class="grid-item">20</div>
  <div class="grid-item">21</div>
  <div class="grid-item">22</div>
  <div class="grid-item">23</div>
  <div class="grid-item">24</div>
  <div class="grid-item">25</div>
</div>
```

```css
.grid {
  background-color: #3d4040;
  display: grid;
  flex-grow: 1;
  gap: 10px;
  grid-template-columns: 1fr 2fr 3fr 4fr 5fr;
  grid-template-rows: 1fr 2fr 3fr 4fr 5fr 6fr;
  height: 100%;
  padding: 20px;
}

.non-subgrid {
  display: grid;
  grid-column: 2 / 4;
  grid-row: 4 / 6;
  gap: 10px;
  grid-template-columns: 2fr 3fr;
  grid-template-rows: 4fr 5fr;
}

.headline {
  align-self: center;
  color: #fff;
  font-size: 40px;
  grid-column: 1 / -1;
}

.grid-item {
  background-color: #55c500;
}

.nested-grid-item {
  background-color: #4097db;
}
```

もし親要素である`.grid`の幅や高さを変えても、子要素の`.non-subgrid`がそれを検知する術はありません。
例えば`.grid`だけを次のように変えたら、表示はこうなってしまいます。

```diff_css
  .grid {
    background-color: #3d4040;
    display: grid;
    flex-grow: 1;
    gap: 10px;
-   grid-template-columns: 1fr 2fr 3fr 4fr 5fr;
+   grid-template-columns: 3fr 3fr 2fr 2fr 1fr;
-   grid-template-rows: 1fr 2fr 3fr 4fr 5fr 6fr;
+   grid-template-rows: 1fr 3fr 2fr 2fr 1fr 1fr;
    height: 100%;
    padding: 20px;
  }
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/612c0a3a-c5e4-e4d3-5079-64f597228b87.png" width="400" alt="" />

## Subgridを使うと

```diff_html
-  <div class="non-subgrid">
+  <div class="subgrid">
     <div class="nested-grid-item">12</div>
     <div class="nested-grid-item">13</div>
     <div class="nested-grid-item">14</div>
     <div class="nested-grid-item">15</div>
  </div>
```

```css
.subgrid {
  display: grid;
  grid-column: 2 / 4;
  grid-row: 4 / 6;
  grid-template-columns: subgrid;
  grid-template-rows: subgrid;
}
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/3fbd1823-2ca4-abdd-88f8-054d7412934a.png" width="400" alt="" />

初期段階の見た目はまったく一緒ですが、subgridを指定することで`grid-template-columns`と`grid-template-rows`に具体的な値を指定しなくても、親のgridの幅を引き継いでくれています。

そのため、親要素のgirdの幅や高さが変わると自動でその変更に従います。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/7b9ab7ff-0094-ef51-a1a9-f2319921300e.png" width="400" alt="" />

## 注意

非常に便利なSubgridですが、現在はまだFirefoxでしか使えません。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/d9ff193f-085d-d1df-2e94-f0fe7ec22c90.png)