CSS Gridの入れ子＆グリッドアイテムの縦横比固定をすると、Chrome / Safariで挙動が違ったので注意。

こんにちは、猫チーズです。

## まとめ
今回のバグは、以下の要素が重なったことによるものでした。
・CSS-Grid in CSS-Grid
・子gridのrow高さに単位`fr`を使用
・paddingの`%`を使った縦横比固定テクニック

**解決策**：親gridのアイテムに`height: 100%;`をかけることで、Safariの挙動をChrome側の挙動と同じにできました。


## EPISODE 1 バグとの遭遇🕷🙀
それは、夜な夜なCSS Gridを駆使して自分のポートフォリオサイトを作っているときでした。

作品をカード状に並べるためにグリッドレイアウトをし、さらに作品カードの中身を左右分割するためにもう一度グリッドレイアウトを使いました。レスポンシブ対応してもカードの縦横比が同じになるために、`padding-bottom: 100%;`も使いました。

<img width="1180" alt="スクリーンショット 2019-10-13 23.58.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268454/47a90d1d-85e2-1f84-0896-8128bdd82548.png">
うん、よしよし。これで完成だ！

達成感を味わいながら、一応確認としてSafariでも開いてみました。
<img width="1176" alt="スクリーンショット 2019-10-13 23.57.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268454/a0c3969c-ff37-5fff-ba04-5c0dfcd11d18.png">
ガーン・・・レイアウト崩れてる・・・

## EPISODE 2 バグの摘出🕷✂️
小一時間かけてバグの本体を発見しました。
問題の部分を最小限に摘出すると、このようなコードです。

```HTML
<body>
	<div id="outer-grid">
		
		<div class="outer-grid-item">
			<div class="aspect-fixer"></div>
			<div class="inner-grid">
				<div class="inner-grid-item left">left</div>
				<div class="inner-grid-item right">right</div>
			</div>
		</div>
		
		<div class="outer-grid-item">
			<div class="aspect-fixer"></div>
			<div class="inner-grid">
				<div class="inner-grid-item left">left</div>
				<div class="inner-grid-item right">right</div>
			</div>
		</div>
		
		<div class="outer-grid-item">
			<div class="aspect-fixer"></div>
			<div class="inner-grid">
				<div class="inner-grid-item left">left</div>
				<div class="inner-grid-item right">right</div>
			</div>
		</div>
		
	</div>
</body>
```

```CSS
<style>
	/* 作品カードを並べる */
	#outer-grid {
		display: grid;
		grid-template: auto / repeat(auto-fit, minmax(200px, 1fr));
		grid-gap: 20px;
	}

	/* 作品カード */
	.outer-grid-item {
		position: relative;
		background: blue;
	}

	/* 作品カードの縦横比を固定させる（16:9） */
	.aspect-fixer {
		padding-bottom: calc(9/16 * 100%);
	}

	/* カードの内部 */
	.inner-grid {
		/* 縦横比固定の追加呪文 */
		position: absolute;
		width: 100%;
		height: 100%;
		top: 0;

		/* 左右分割 */
		display: grid;
		grid-template: 1fr / 1fr 1fr;
	}

	/* 作品カードの左側 */
	.inner-grid-item.left {
		background: red;
	}

	/* 作品カードの右側 */
	.inner-grid-item.right {
		background: yellow;
	}
</style>
```

比率固定が分かりやすいように16:9にしています。
このコードをChrome / Safariそれぞれで開くと次のような違いが出ました。

**Chrome**
![chrome.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268454/f7a4f850-a00b-d102-ebd5-13bd17d33657.gif)

**Safari**
![safari.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268454/dd1abab1-5d71-3aaf-902e-86b691bd8238.gif)

カード内部の左側：赤色
カード内部の右側：黄色
カード自体の背景：青色

赤色&黄色部分の高さ指定にCSS Gridの`1fr`（100%と同じようなもの）を使っています。
Chromeでは`1fr`でカードいっぱいの高さになり、Safariでは同じ`1fr`でもコンテンツ分しか高さが確保されていません。
バグはここに潜んでいました。

## EPISODE 3 バグの駆除🕷🔫
さらに何十分の格闘を続けた末に、駆除方法を発見しました。

先ほどのCSSの`.outer-grid-item`に`height: 100%;`を追記します。

```CSS
/* 作品カード */
.outer-grid-item {
	position: relative;
	background: blue;
	height: 100%;	/* これが重要🔫 */
}
```

こうすることで、Safariで`1fr`を使ってもちゃんとカードの高さいっぱいに広がるのでした。

完

## 猫チーズ
個人でサービスを作って生きていくために奮闘中です。
UX/UIデザイナーをしたり、フロントエンドエンジニアもしています。

**Hello 猫チーズ | 猫チーズと擬似会話ができるブログ**
https://blog.miyauchi-akira.app/post/20190927/

**Twitter**
https://twitter.com/miyauchoi

**ポートフォリオ**
https://miyauchi-akira.app