こんにちは、猫チーズです。
まとめ
今回のバグは、以下の要素が重なったことによるものでした。
・CSS-Grid in CSS-Grid
・子gridのrow高さに単位fr
を使用
・paddingの%
を使った縦横比固定テクニック
解決策:親gridのアイテムにheight: 100%;
をかけることで、Safariの挙動をChrome側の挙動と同じにできました。
EPISODE 1 バグとの遭遇🕷🙀
それは、夜な夜なCSS Gridを駆使して自分のポートフォリオサイトを作っているときでした。
作品をカード状に並べるためにグリッドレイアウトをし、さらに作品カードの中身を左右分割するためにもう一度グリッドレイアウトを使いました。レスポンシブ対応してもカードの縦横比が同じになるために、padding-bottom: 100%;
も使いました。

達成感を味わいながら、一応確認としてSafariでも開いてみました。
ガーン・・・レイアウト崩れてる・・・
EPISODE 2 バグの摘出🕷✂️
小一時間かけてバグの本体を発見しました。
問題の部分を最小限に摘出すると、このようなコードです。
<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>
<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それぞれで開くと次のような違いが出ました。
カード内部の左側:赤色
カード内部の右側:黄色
カード自体の背景:青色
赤色&黄色部分の高さ指定にCSS Gridの1fr
(100%と同じようなもの)を使っています。
Chromeでは1fr
でカードいっぱいの高さになり、Safariでは同じ1fr
でもコンテンツ分しか高さが確保されていません。
バグはここに潜んでいました。
EPISODE 3 バグの駆除🕷🔫
さらに何十分の格闘を続けた末に、駆除方法を発見しました。
先ほどのCSSの.outer-grid-item
にheight: 100%;
を追記します。
/* 作品カード */
.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