初心者にも優しいIE対応したgridレイアウト

Blog

今年も残りわずかとなりました。
日もすっかり短くなって冬ですね、私はやまだです。

そんな今年2017年はWeb業界的にはgrid元年だったということで、今のうちにgridレイアウトについて触れたいと思います。
一から十まで触れると余計頭がこんがらがりやすいので、まだgridに触れたことない人でも入りやすく、かつ躓かない程度に。
しっかりとIE対策もして、流行に乗り遅れないようにしましょう!

親要素のプロパティ

まずは親要素のdisplayプロパティをgridにします。

.hoge {
    display: grid;
}

続いて、各要素のサイズを指定していくわけですが、コードを書く前に図を書いてみると分かりやすくなると思います。
今回は色ごとに分かれたdiv要素に対して、gridレイアウトを適用します。

どこで分割するかを可視化して、縦と横のサイズを明確にします。
これが親要素に付与するgrid-template-columnsgrid-template-rowsです。

.container {
    width: 960px;
    height: 580px;

    display: grid;
    grid-template-columns: 600px 360px;
    grid-template-rows: 180px 1fr 1fr;
}

ここで出ました。新しい単位、1fr
これは「余白がある場合、その要素をどれだけ拡大するか」を設定します。
今回のように1frを二つのときは、2分割して1:1で割り振られます。
仮にgrid-template-rows: 180px 2fr 1fr;とすると、3分割して2:1で割り振られます。
結果はこんな感じ。
widthheightの指定は省略できますが、frを使用する際には親要素の幅や高さが必要になるため注意してください。)

子要素のプロパティ

続いては、子要素の設定です。
子要素の設定は、分割した線に番号を振ると分かりやすくなります。
何番から何番のエリアに表示したいかを設定します。

.pink {
    grid-column: 1 / 3;
    grid-row: 1 / 2;
}

.blue {
    grid-column: 1 / 2;
    grid-row: 2 / 4;
}

.green {
    grid-column: 2 / 3;
    grid-row: 2 / 3;
}

.yellow {
    grid-column: 2 / 3;
    grid-row: 3 / 4;
}

これでOK!!と思ったら、gulpのコンパイルしたところ、以下のようなこと言われました。

gulp-postcss: css/style.css
autoprefixer: /src/scss/grid.css:6:2: IE supports only grid-row with / and span. You should add grid: false option to Autoprefixer and use some JS grid polyfill for full spec support

要するに、autoprefixerさんが言うには「うちはその書き方サポートしてないから自分でやって!」みたいなこと。
でもどうしたらいいの?と思い、調べたところ、どうやら私が使用していたpostcssのautoprefixerのバージョンが古かったようです。
もし同じことが起こった人は、これを機にアップデートしてあげた方がよいかもしれません。
autoprefixer releases

万が一、アップデートできない状況にある方は、特定のプロパティだけ除外するオプションがあるようです。
という訳で、そんなときはgulpfile.jsを書き換えます。

var gulp = require('gulp');
var postcss = require('gulp-postcss');

gulp.task('sass', function(){
    gulp.src('./src/scss/**/*.scss')
    .pipe(postcss(
        require('autoprefixer')({
            grid: false
        })
    ))
})

IEにも対応しよう

autoprefixerが問題なくベンダープレフィクスを付けてくれれば特に対応は必要ないかと思います。
そうでない場合は、IE用にベンダープレフィクス-ms-を付け加えた形に書き換えます。
その際、プロパティ名も少し変わるため注意してください。
また子要素に設定する値もどこの線からどこの線までという記述ではなく、エリアの考え方になるため、ここも注意。
とは言ってもスタート位置の線の番号と同じものになるため、難しく考えない方がよいかもしれません。

.container {
    width: 960px;
    height: 580px;

    display: grid;
    grid-template-columns: 600px 360px;
    grid-template-rows: 180px 1fr 1fr;
    -ms-display: grid;
    -ms-grid-columns: 600px 360px;
    -ms-grid-rows: 180px 1fr 1fr;
}

.pink {
    grid-column: 1 / 3;
    grid-row: 1 / 2;
    -ms-grid-columns: 1;
    -ms-grid-rows: 1;
}

.blue {
    grid-column: 1 / 2;
    grid-row: 2 / 4;
    -ms-grid-columns: 1;
    -ms-grid-rows: 2;
}

.green {
    grid-column: 2 / 3;
    grid-row: 2 / 3;
    -ms-grid-columns: 2;
    -ms-grid-rows: 2;
}

.yellow {
    grid-column: 2 / 3;
    grid-row: 3 / 4;
    -ms-grid-columns: 2;
    -ms-grid-rows: 3;
}

今回は省略した形で記述しましたが、本来はもっと細かくプロパティが分かれています。
まずはgridレイアウトの使い所を理解してから、細かいプロパティを理解していく方法もありかなと思います。
慣れてくるとレイアウトのためにdiv要素を増やしたりもせずに済むため、HTMLも短くすることができそうです。
GRID GARDENというゲーム感覚で覚えられるサイトもあるようですので、是非gridレイアウトを覚えて気持ちよく新年を迎えましょう!