gap に注意
この配置方法では、IE で gap を再現することができません。先程のグリッドに grid-gap: 1rem を指定すると、Chrome では正常に動きますが、IE では以下のようになってしまいます。
IE が解釈できるグリッドは、まずテンプレートを作って(3×2など)、グリッドライン番号でアイテムの開始位置を指定して、そこからどれだけアイテムを伸ばすかを指定するというものです。
そして、IE のグリッドには gap がありません。そこで Autoprefixer は (grid-)gap を見つけると、自動的にテンプレートを変更して、gap を再現しようとします。
Autoprefixer の動作
以下は、先程までのグリッドとは関係なく、手動配置グリッドを作る例です。3×3 のグリッドですね。
.grid-container {
display: grid;
grid-gap: 1rem 2rem;
grid-template:
"a c c" 5rem
"b c c" 5rem
"b d d" 5rem
/1fr 1fr 1fr;
.item-a { grid-area: a }
.item-b { grid-area: b }
.item-c { grid-area: c }
.item-d { grid-area: d }
}
これがコンパイルされると、-ms-プレフィックスのついたプロパティが追加されていることが分かります。
.grid-container {
display: -ms-grid;
display: grid;
grid-gap: 1rem 2rem;
-ms-grid-rows: 5rem 1rem 5rem 1rem 5rem;
-ms-grid-columns: 1fr 2rem 1fr 2rem 1fr;
grid-template: "a c c" 5rem "b c c" 5rem "b d d" 5rem/1fr 1fr 1fr;
}
注目すべきは -ms-grid-columns / -ms-grid-rows プロパティです。gap が縦方向に 1rem なので、行の高さ 5rem の間に 1rem が挿入されています。
横方向も同様に、grid-gap がこちらは 2rem なので、列の幅 1fr の間に 2rem が挿入されています。
つまり、IE で表示するグリッドは 5×5 に変更されているわけです。
次に、アイテムごとのコンパイル結果を見てみましょう。
.grid-container .item-a {
-ms-grid-row: 1;
-ms-grid-column: 1;
grid-area: a;
}
.grid-container .item-b {
-ms-grid-row: 3;
-ms-grid-row-span: 3;
-ms-grid-column: 1;
grid-area: b;
}
.grid-container .item-c {
-ms-grid-row: 1;
-ms-grid-row-span: 3;
-ms-grid-column: 3;
-ms-grid-column-span: 3;
grid-area: c;
}
.grid-container .item-d {
-ms-grid-row: 5;
-ms-grid-column: 3;
-ms-grid-column-span: 3;
grid-area: d;
}
こちらにも -ms- の付いたプロパティが追加されています。これらのプロパティを覚える必要はないので、適当に流します。
アイテムの開始位置は、縦方向は -ms-grid-row、横方向は -ms-grid-column で指定します。アイテムをそこからどれだけ伸ばすかは、-span で終わるプロパティで指定します。
これらのプロパティで指定されている値を見ると、すべて奇数になっているのが分かると思います。これは、偶数番目のグリッドラインは gap 用の行・列だからです。
このように、gap を表す行・列を自動で追加し、更にそこにアイテムを配置しないことで、Autoprefixer は gap を IE でも再現しています。
アイテムの位置を上書きしている
改めて、今回の配置方法で作ったグリッドを見てみましょう。
なぜ上の比較画像のようになるかというと、今回の配置方法は、Autoprefixer が自動でやってくれるアイテムの配置を上書きしているからです。
比較画像のアイテムAのコンパイル結果を見てみると、-span 系のプロパティに偶数が入っています。これは、今回の配置方法で grid-column / grid-row を指定したからです。
.grid-container .item-a {
-ms-grid-column: 1;
-ms-grid-column-span: 2;
grid-column: 1/3;
-ms-grid-row: 1;
-ms-grid-row-span: 2;
grid-row: 1/3;
}
要するに、なぜ IE 側のアイテムAが小さいかというと、gap 用の行・列が増えているにも拘らず、アイテム位置の指定はそのままになっているからです。
上の Chrome と比較してみると、アイテムBとその横の gap の部分は、IE では全く使われていません。それもそのはずで、IE では 5×5 のグリッドとなっているのに、3×3 のグリッドのつもりでアイテムを配置しているのです。
それでもアイテムを被せたい場合
もし今回の配置方法を、gap ありで IE でも正しく表示したいなら、自分で -ms- 付きのプロパティも書いて、gap 用の行・列を飛ばした値を入れる必要があります。
.grid-container {
.item-a {
grid-column: 1 / 3;
grid-row: 1 / 3;
-ms-grid-column: 1;
-ms-grid-column-span: 3;
-ms-grid-row: 1;
-ms-grid-row-span: 3;
}
.item-b {
grid-column: 3 / 4;
grid-row: 1 / 4;
-ms-grid-column: 5;
-ms-grid-row: 1;
-ms-grid-row-span: 5;
}
.item-c {
grid-column: 1 / 4;
grid-row: 3 / 4;
-ms-grid-column: 1;
-ms-grid-column-span: 5;
-ms-grid-row: 5;
}
}
はい。これで IE でも gap を(擬似的に)使いつつ、アイテムを被せることができました。
辛いですね。ベンダープレフィックスを自分で書くなんて馬鹿げたことはやめましょう。
終わりに
今回の配置方法は、どうしてもアイテム同士を被せたいという場面以外では無用の長物です。他の配置ならグリッドラインなど考える必要もありません。
正直使わないと思ったなら、今回の内容は丸々忘れてしまいましょう。前回の内容だけで充分です。