CSS Grid レイアウトでハマったheightを0にしたpaddingでの高さ指定
CSS Grid レイアウト + paddingでの高さ指定をしたらIE11とEdgeでは高さが反映されないということがあったのでそのメモです。
グリッド要素のheightを0にして高さをpaddingでの比率指定にしてみた
下の画像のようなレイアウトをCSS Grid レイアウトで実装してみました。
この記事ではよりシンプルにするためにただブロック分けした状態で実装していきます。
ブロック分けした状態で実装
これをどうコーディングしたのかというと、まず全体を覆うコンテナーに display: grid; を指定し、グリッドコンテナーにします。そして中を縦に3分割、横に3分割しそれぞれ grid-row などのプロパティを使って要素を割り当てました。
そして、"画像" の部分については16:9の比率でレスポンシブさせたかったので height を 0 、padding-bottom を 56.25% に指定しました。実際に画像を入れる場合は、16:9にした要素に背景画像を設定します。
ソースコードはこんな感じで書きました。
HTML
<div class="test-container"> <h3 class="test-title">タイトル</h3> <p class="test-text">テキストテキストテキストテキスト</p> <p class="test-img">画像</p> <p class="test-img-text"">ボタン></p> </div>
CSS
.test-container { display: grid; grid-template-rows: auto auto 30px; grid-template-columns: 1fr 20px 40%; display: -ms-grid; -ms-grid-rows: auto auto 30px; -ms-grid-columns: 1fr 20px 40%; background-color: gainsboro; } .test-title { margin: 0; grid-row: 1 / 2; grid-column: 1 / 2; -ms-grid-row: 1; -ms-grid-column: 1; background-color: palegreen; } .test-text { margin: 0; grid-row: 2 / 4; grid-column: 1 / 2; -ms-grid-row: 2; -ms-grid-row-span: 2; -ms-grid-column: 1; background-color: pink; } .test-img { margin: 0; grid-row: 1 / 3; grid-column: 3 / 4; -ms-grid-row: 1; -ms-grid-row-span: 2; -ms-grid-column: 3; height: 0; padding-bottom: 56.25%; background-color: powderblue; } .test-img-text { margin: 0; grid-row: 3 / 4; grid-column: 3 / 4; -ms-grid-row: 3; -ms-grid-column: 3; background-color: khaki; }
ChromeとIEでのスクリーンショット比較
それでは問題のIEでの表示確認をします。こちらがChromeとIEでの表示比較画像です。
IEだと"画像"部分の高さが保てていないのがわかります。どうやら、グリッド要素(gird指定した要素の直接の子要素)の height を0にして padding-bottom で高さを保とうとしたのがまずかったようです。混ぜるな危険です。
これはEdgeでも同じような表示崩れを確認できました。
グリッドレイアウトのプロパティとpaddingでの比率固定を分離
ということで、"画像"要素にpadding-bottom での比率指定をし、その外側に一つdivを追加してそこにgrid指定をすることにしました。ソースコードはこんな感じです。
HTML
<div class="test-container"> <h3 class="test-title">タイトル</h3> <p class="test-text">テキストテキストテキストテキスト</p> <div class="test-img-wrap"> <p class="test-img">画像</p> </div> <p class="test-img-text"">ボタン></p> </div>
CSS
.test-container { display: grid; grid-template-rows: auto auto 30px; grid-template-columns: 1fr 20px 40%; display: -ms-grid; -ms-grid-rows: auto auto 30px; -ms-grid-columns: 1fr 20px 40%; background-color: gainsboro; } .test-title { margin: 0; grid-row: 1 / 2; grid-column: 1 / 2; -ms-grid-row: 1; -ms-grid-column: 1; background-color: palegreen; } .test-text { margin: 0; grid-row: 2 / 4; grid-column: 1 / 2; -ms-grid-row: 2; -ms-grid-row-span: 2; -ms-grid-column: 1; background-color: pink; } .test-img-wrap { margin: 0; grid-row: 1 / 3; grid-column: 3 / 4; -ms-grid-row: 1; -ms-grid-row-span: 2; -ms-grid-column: 3; background-color: powderblue; } .test-img { height: 0; margin: 0; padding-bottom: 56.25%; } .test-img-text { margin: 0; grid-row: 3 / 4; grid-column: 3 / 4; -ms-grid-row: 3; -ms-grid-column: 3; background-color: khaki; }
"画像" の外側に一つdivを用意してみましたが、それ以外の内容はほぼ変えてないです。それでは、ChromeとIEの比較画像を見てみましょう。
ChromeとIEでのスクリーンショット比較
IEでもちゃんと高さを保てているようです!
今回は"画像"の外側に一つdivを入れることで対処しました。2019/6時点では私と同じようにgird要素のheightを0にしたらハマったという現象について書かれた記事が見当たらなかったので、もしかしたら今後他の対応方法も見つかるかもしれません!
下に実際にコーディングした結果を載せておきます。モダンブラウザでは全く同じものが2つ並んでいるようにしか見えませんが、IEやEdgeで確認すると一つ目の"画像"が潰れているのがわかるかと思います。
①グリッド要素のheightを0にした状態
タイトル
テキストテキストテキストテキスト
画像
詳しくみる>
②グリッド要素とheight 0 を分離
タイトル
テキストテキストテキストテキスト
画像
ボタン>
おまけ
もう一つ気づいたことがあったのでメモしておきます。「IEは、grid-row-start: 2; だけでは全て自動で並べ変わってくれない問題」です。
HTML要素の並び順を変えたい場合、コンテナにdisplay: grid;を指定し(グリッドコンテナー)、グリッドコンテナー直接の子要素(グリッド要素)に grid-row-start: 2;などを指定します。
これはモダンブラウザであれば、並び順を変更したいグリッド要素にのみgrid-row-start: 2;などを指定すれば他のグリッド要素は、変更した要素を考慮した並びに勝手に並び変わります。
しかし、IEについては全てのグリッド要素に順番指定しないといけないようでした。ちなみにベンダープレフィックスは "-ms-grid-row" です。
追記
- 上記ではIE11対応の為にベンダープレフィックスを手書きしていますが、Autoprefixer がかなり充実しているようです。webpackやgulpを使っている場合は Autoprefixer を取り入れると楽に実装できます(2019年10月)。