autoprefixer で display: grid が IE で崩れる

  • CSS

webpack の autoprefixer を使っていて、grid レイアウトが IE で潰れてしまい崩れが発生。IE への対応はされているはずなのでコンパイル後のコードを見てみると、

-ms-grid-rows: 20px 1fr;
-ms-grid-columns: auto;

こんな感じでベンダープレフィックスは追加されているものの、本来 grid レイアウトの IE 対応時に追加される下記のような nth-child() 系のスタイルが生成されていませんでした。

    .l-footer > *:nth-child(1) {
    -ms-grid-row: 1;
    -ms-grid-column: 1; }
    .l-footer > *:nth-child(2) {
    -ms-grid-row: 1;
    -ms-grid-column: 2; }
    .l-footer > *:nth-child(3) {
    -ms-grid-row: 2;
    -ms-grid-column: 1; }
    .l-footer > *:nth-child(4) {
    -ms-grid-row: 2;
    -ms-grid-column: 2; } }

原因

(1) autoprefixer の grid プロパティを autoplace にしていない

grid: true もしくは grid: no-autoplace だと自動配置が行われません。自動配置を行う場合は autoplace に設定します。

(2) grid-template-areas, grid-area を指定していない

IE 以外のブラウザでは grid-area の指定のないものは全て自動配置が行われます。もし、grid-area を設定していたりしていなかったりすると、他のブラウザではいい感じに自動配置を行ってくれますが、IE だと意図しない配置になります。

また、プロパティが足りないと IE の変換が正しく行われません。

.grid {
  grid-template:
    "head head" auto
    "main side" auto
    "foot foot" auto /
    900px 1fr;
}
.head { grid-area: head; }
.main { grid-area: main; }
.side { grid-area: side; }
.foot { grid-area: foot; }

IE では自動配置が効かないので、細かい指定を行うときは grid-template と grid-area を使って明示してあげます。

(1) インラインタグを使用している

<div class="grid">
  <div></div>
  <div></div>
  <small></small>
</div>

これは細かい検証をしていませんが、small タグを grid の子要素として設定していた時に small タグの部分だけが一番上まで詰まって重なってしまっていました。この例では div で囲むことで解消されました。もしかすると、IE ではインラインタグを grid として使えないのかもしれません。

<div class="grid">
  <div></div>
  <div></div>
+ <div>
    <small></small>
+ </div>
</div>

(4) 要素が動的に生成されている

冒頭でも書いた通り、IE の自動配置については nth-child(n) のように子要素を自動的に判断して、いい感じに配置するように autoprefixer が頑張ってくれています。ですが php などで動的に要素を生成すると、autoprefixer の自動生成が行われないため、崩れます。

もし IE で対応したい場合は display: flex; を使うと綺麗にはなりませんが崩れすぎた状態は回避できます。