CSS Grid Layout の auto-fit を擬似的に IE11 で実現させる

CSS Grid Layout の auto-fit を擬似的に IE11 で実現させる


CSS Grid Layout を使いますとウェブの表現力があがりますね。「グリッドレイアウト」などでググってみてください。おしゃれなサイトがいっぱい紹介されています。このブログもそろそろグリッドレイアウトで作り直してみようかと思っています。



はてなブログ グリッドレイアウト開発環境

ということで、まず手始めに、下記記事で、はてなブログテーマのグリッドレイアウトSASS開発環境を作ってみたのですが、IE11 対応をどうするかという問題にぶち当たっています。この開発環境では、autoprefixer を導入していますので、自動的にベンダープレフィックスを付けてくれるのですが、auto-fill, auto-fit には対応していません。

それをなんとかしようということです。


www.imuza.com


auto-fit を使ってブロックを並べる

はてなブログのトップページを一覧表示にし、記事を横並びにし、なおかつレスポンシブにしようということです。どちらかといいますと、display:flex のほうが向いているかとは思いますが、グリッドレイアウトの auto-fit を使えば、メディアクエリなしで横並びのブロックの数を1, 2, 3...と変化させることができます。

下のサンプルを別ウィンドウか別タブで開いてブラウザのサイズを変更してみてください。ブロックが自動的に伸縮して、ブロックの横幅が最小 300pxで数が変化します。


See the Pen -ms-grid by ausnichts (@ausnichts) on CodePen.

新しいタブで開く


コードは、

.grid-container {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  grid-gap: 2vw;
}

これだけです。


auto-fit を擬似的に IE11 で実現させる

repeat() を書き換える

ブロックの数の変化はメディアクエリに頼るしかありませんので、まずは、repeat() を書き換えます。

sass のコードを、

$column: 3;
.grid-container {
  display: grid;
  grid-template-columns: repeat($column, 1fr);
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  grid-gap: 2vw;
}

としますと、css は、

.grid-container {
    display: -ms-grid;
    display: grid;
    -ms-grid-columns: (1fr)[3];
        grid-template-columns: repeat(3, 1fr);
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    grid-gap: 2vw;
}

となり、Chrome などのモダンブラウザでは、

f:id:ausnichts:20181127142108j:plain

となり、メディアクエリなしでもブロック数が変化します。しかし、IE11 では、

f:id:ausnichts:20181127142050j:plain

ブロックが重なってしまいます。


グリッドトラックを指定する

-ms-grid-row-ms-grid-column を使って1ブロックずつグリッドトラックを指定してみます。


$child: 10;
$column: 3;
.grid-container {
  display: grid;
  grid-template-columns: repeat($column, 1fr);
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  grid-gap: 2vw;

  @for $i from 1 through $child {
    div:nth-child(#{$i}) {
      $j: $i % $column;
      @if $j == 0 { $j: $column; }
      -ms-grid-column: $j;
      -ms-grid-row: ceil($i / $column);
    }
  }
}

css は、

.grid-container {
    display: -ms-grid;
    display: grid;
    -ms-grid-columns: (1fr)[3];
        grid-template-columns: repeat(3, 1fr);
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    grid-gap: 2vw;
}

.grid-container div:nth-child(1) {
    -ms-grid-column: 1;
    -ms-grid-row: 1;
}

.grid-container div:nth-child(2) {
    -ms-grid-column: 2;
    -ms-grid-row: 1;
}

.grid-container div:nth-child(3) {
    -ms-grid-column: 3;
    -ms-grid-row: 1;
}

.grid-container div:nth-child(4) {
    -ms-grid-column: 1;
    -ms-grid-row: 2;
}

.grid-container div:nth-child(5) {
    -ms-grid-column: 2;
    -ms-grid-row: 2;
}

.grid-container div:nth-child(6) {
    -ms-grid-column: 3;
    -ms-grid-row: 2;
}

.grid-container div:nth-child(7) {
    -ms-grid-column: 1;
    -ms-grid-row: 3;
}

.grid-container div:nth-child(8) {
    -ms-grid-column: 2;
    -ms-grid-row: 3;
}

.grid-container div:nth-child(9) {
    -ms-grid-column: 3;
    -ms-grid-row: 3;
}

.grid-container div:nth-child(10) {
    -ms-grid-column: 1;
    -ms-grid-row: 4;
}

.grid-container div {
    font-size: 30px;
    text-align: center;
    border: 1px solid red;
}

となり、

f:id:ausnichts:20181127142101j:plain

grid-gap 以外は実現できます。


と、 ここまではきたのですが、grid-gap を実現しようとしますと、あちらを立てればこちらが立たず状態でうまくいきません。autoprefixer は、grid-area を使えば、

.grid-container {
    display: -ms-grid;
    display: grid;
    -ms-grid-columns: 1fr 2vw 1fr 2vw 1fr;
    grid-template-columns: repeat(3, 1fr);
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    grid-gap: 2vw;
    -ms-grid-rows: auto 2vw auto 2vw auto 2vw auto;
    grid-template-areas: "r1c1 r1c2 r1c3 " "r2c1 r2c2 r2c3 " "r3c1 r3c2 r3c3 " "r4c1 r4c2 r4c3 " ;
}

こんな風にギャップをひとつのグリッドトラックに変換してくれるのですが、これをやりますとモダンブラウザのほうがおかしくなってしまいます。

んー、むずかしい! と、いいますか、そもそも無駄なことをやっているような…(笑)。

次回です。