LoginSignup
9
6

More than 3 years have passed since last update.

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

Posted at

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

まとめ

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

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

EPISODE 1 バグとの遭遇🕷🙀

それは、夜な夜なCSS Gridを駆使して自分のポートフォリオサイトを作っているときでした。

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

スクリーンショット 2019-10-13 23.58.06.png
うん、よしよし。これで完成だ!

達成感を味わいながら、一応確認としてSafariでも開いてみました。
スクリーンショット 2019-10-13 23.57.44.png
ガーン・・・レイアウト崩れてる・・・

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それぞれで開くと次のような違いが出ました。

Chrome
chrome.gif

Safari
safari.gif

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

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

EPISODE 3 バグの駆除🕷🔫

さらに何十分の格闘を続けた末に、駆除方法を発見しました。

先ほどのCSSの.outer-grid-itemheight: 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

9
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
6