CSS Grid Layoutをガッツリ使った所感

  • 7
    いいね
  • 0
    コメント

CSS Grid Layout Moduleはレイアウトを構築できる新しいCSSの仕様です。従来はfloatやFlexbox( display: flex )で対応していたようなレイアウトを構築できます。

2017年4月にリニューアルした私の個人プロジェクト「Beautifl - Flash Gallery」でガシガシCSS Grid Layoutを使ったので、所感をお伝えします。一般公開されている事例でCSS Grid Layoutを使っているサイトを見かけないので、ベンチマークとしてみてもらえたら幸いです。

beautifl.jpg

Beautifl - Flash Galleryは2009年に公開したサイト。従来はIE7対応をベースに構築してましたが、リニューアルでは脱jQueryの方針のもと、Vue.jsやCSS Grid Layoutを導入。WAI-ARIAや部分的にHTTP/2対応もしてます。

CSS Grid Layoutの所感

CSS Grid Layoutの良かった点

  • floatやFlexboxだとDOMが入れ子構造となりがちだが、CSS Grid Layoutだと入れ子構造を使わずに構築できる
  • DOM構造の自由度が上がるので、モバイル・デスクトップのレスポンシブに対応しやすい
  • DOM要素がシンプルになるので、動的に画面が変化するSPA/RIAの構築が楽になる

Beautiflはいろんなレイアウトに変化しますがCSS Grid Layoutをベースに構築しました。

CSS Grid Layoutの困った点

  • 最新ブラウザしか使えない(主要ブラウザは2017年3月に対応したばかり)
  • IEとEdgeは古い仕様で実装されているので、工夫が必要
  • 検索エンジンのインデックス収集に支障ないか不安
  • Polyfillはイマイチ信用できない

CSS Grid Layoutは便利ですし、SPAなど必要な場面でもっと普及して欲しいと思っています。しかし、特定のブラウザ、特にIE 11の存在を無視できないと思います。IE 11は今やウェブ業界の足かせと思っているコーダーは多いでしょうが、記事「各Windows OSでのInternet Explorerのサポート終了時期 - @IT」によるとIE 11は2020年まで生き延びているはずです💀。

ただ実は古い仕様とはいえCSS Grid Layoutに対応しているのは救いです👼

背景

CSS Grid Layoutの入門記事

CSS Grid Layoutの解説記事は次がわかりやすいでしょう。私はCodeGridで学びました。Webクリエイターボックスの記事は図版入りでわかりやすいですね。

対応環境

CSS Grid Layoutが対応しているのは、最新のブラウザのみ(参照「Can I use...」)。2017年3月に足並みを揃えたように各種ブラウザが一斉に対応しました。

  • Chrome 57 (2017年3月)
  • Firefox 52 (2017年3月)
  • Safari 10.1 (2017年3月)
  • iOS Safari 10.3 (2017年3月)
  • IE 10 (2012年9月)
  • Edge 12 (2015年1月)

一般的なサイトでは動作対象ブラウザを「IE 11以上、Chrome最新版、Firefox最新版」としているサイトも多いでしょう。IEとEdgeが先行して実装してていたおかげで、比較的導入しやすい土台が揃っています。

spec.png

CSS Grid Layoutで困った点へのアプローチを紹介

シンプルな例でクロスブラウザ対応を考える

まずはCSS Grid Layoutの説明。CSS Grid Layoutでは、レイアウトを格子状に考えます。どの格子に要素を割り当てるか、という考え方で使います。

まずはレイアウトを区切ります。

Web 1920 – 10.png

CSSでは次のように書きます。1frという単位は可変するところに指定します。

.my-grid {
  display: grid;
  grid-template-columns: 200px 1fr;
  grid-template-rows: 50px 1fr 50px;
}

ヘッダーやサイドバー、メインコンテンツ、フッターの4要素を割り当てます。

Web 1920 – 2.png

CSSでは次のように指定します。


header {
  grid-column-start: 1;
  grid-column-end: 3;
  grid-row: 1;
}

aside {
  grid-column: 1;
  grid-row-start: 2;
  grid-row-end: 4;
}

main {
  grid-column: 2;
  grid-row: 2;
}

footer {
  grid-column: 2;
  grid-row: 3;
}

次のURLでサンプルを公開しているので、アクセスしてみてください。

▶ 標準仕様のみ対応版のデモ
https://ics-creative.github.io/170414_css_grid/dist/1.html

ChromeやSafari、Firefoxなど最新のブラウザーでは期待通りに表示されています。

sample_01_modern.jpg

これでめでたく完成。と思いきやIE 11やEdge 14で見てみましょう。

sample_01.jpg

はい、全滅ですね。

IEとEdgeを対応させる

IE 11やEdge 14ではベンダープレフィックスが必要です。次はコードの一部ですが、-ms-を付与したCSSのコードです。

.my-grid {
  display: -ms-grid;
  display: grid;
  -ms-grid-columns: 200px 1fr;
  grid-template-columns: 200px 1fr;
  -ms-grid-rows: 50px 1fr 50px;
  grid-template-rows: 50px 1fr 50px;
}
header {
  -ms-grid-column: 1;
  grid-column-start: 1;
  grid-column-end: 3;
  -ms-grid-row: 1;
  grid-row: 1;
}

ちなみにベンダープレフィックスを手動で付与するのは人類がなすべきことではありません。Autoprefixerという文明の利器を使いましょう。Autoprefixerは @tonkotsuboy_com の記事「CSSベンダープレフィックス-webkit-を今この瞬間に辞める為のAutoprefixerの導入とお薦め設定」が参考になります。

さぁ、これでIE 11やEdge 14で見てみます。

▶ AutoPrefixer対応版
https://ics-creative.github.io/170414_css_grid/dist/2.html

sample_02.jpg

まだ微妙・・・😝 ヘッダーが横一行になっていなかったり、サイドバーが行二列に突き抜けていません。背景の赤色が見えています。

ベンダープレフィックスを付けるだけでは十分とは言えない

実はIE 11やEdge 14はCSS Grid Layoutが使えるとは言え、古い仕様(Grid Layout | W3C Working Draft 7 April 2011)でブラウザに実装されています。標準のCSS Grid Layoutと古い仕様では次のような違いがあります

  • 使えるプロパティーが少ない
  • Autoprefixerで変換しきれないプロパティーがある
  • 片方にはあって、片方にない仕様がある

レイアウト崩れの原因は行・列の結合部分に関する部分です。ここに古い仕様と標準仕様の違いがあります。

標準の仕様では、格子状の分割線①から③まで指定するという方法です。

header {
  grid-column-start: 1;
  grid-column-end: 3;
  grid-row: 1;
}

対してIE 11やEdge 14の仕様は①からいくつのセルを結合するかという指定です。

header {
  -ms-grid-column: 1;
  -ms-grid-column-span: 2; /* MS対策(手動) */
  -ms-grid-row: 1;
}

標準仕様ではgrid-column-endで、古い仕様は-ms-grid-column-spanで、仕様自体が異なっています。そのため、Autoprefixerではこの変換は解消できません。ここは自分でコードを書き足して対応します。

▶ IEとEdgeの対応コード追加。
https://ics-creative.github.io/170414_css_grid/dist/3.html

やっと、期待通りに表示できるようになりました。

sample_03.jpg

SASSのmixinを用意して対処した

簡単に対処するには、SASSで次のmixinを使うといいでしょう。これとAutoprefixerを組み合わせると、無事にクロスブラウザ対応ができます。

/** CSS Grid Layoutで複数の行を指定するmixin */
@mixin create-grid-column-span($start, $end) {
  grid-column-start: $start;
  grid-column-end: $end;
  -ms-grid-column-span: $end - $start;
}

/** CSS Grid Layoutで複数の列を指定するmixin */
@mixin create-grid-row-span($start, $end) {
  grid-row-start: $start;
  grid-row-end: $end;
  -ms-grid-row-span: $end - $start;
}

/* 使用例 */
header {
  @include create-grid-column-span(1, 3);
  grid-row: 1;
}

完成品のサンプルはこちらになります。SASSのmixinと、Autoprefixerのあわせ技で対応しています。

▶ 完成品のサンプル
https://ics-creative.github.io/170414_css_grid/dist/

ソースコードはGitHubで公開しているので、よかったら使ってくださいませ。

https://github.com/ics-creative/170414_css_grid

検索エンジンのインデックス収集に支障がないか不安

IE 11、Edge 14まで含め様々なブラウザに対応できたので安心していましたが、落とし穴がありました。検索エンジンでインデックスされるように、Google Search ConsoleのFetch as Googleにだしてみました。

google-search-console.jpg

すると、CSS Grid Layoutを使った部分が解釈されずレンダリングされてしまいました。検索エンジンにはレイアウトが崩れたまま解析されてそうで、不安が大いに残ります。検索流入に影響があるかは経過を眺めながら分析していこうと思います。

なお、後述のPolyfillを入れると検索エンジンでレンダリングされましたが、Polyfillにはいろんな問題があったため結局Polyfillの導入を諦めました。

あてにならないPolyfill

Polyfillを探して実験的に試しました。

FremyCompany/css-grid-polyfill: A working implementation of css grids for current browsers.

Polyfillを入れると一応CSS Grid Layoutが解釈されるようになります。

  • id属性が付与されまくる
  • overflowの解釈・スクロールバーの発生有無が想定と異なった
  • CSS Grid Layoutとはあまり関係ない部分のレイアウトが崩れた
  • PolyfillのJSライブラリの容量がでかい(78 KB)
  • IE 11とEdge 14にも、Polyfillが効いてしまう(エンバグが発生)

じっくり取り組んだり、他のPolyfillを探せば解決できたかもしれませんが、Polyfillを使わず、最新のブラウザが普及するのを待つ方が本質的だと考え、採用を見送りました。

まとめ

CSS Grid Layoutが利用できる最新ブラウザが十分に浸透するまで数ヶ月かかると思いますが、採用したサイトが今後増えてくると思います。DOMの要素の順番や親子構造とレイアウトを分離できるのが利点なので、適材適所として選択肢の1つに入れておくといいでしょう。

冒頭で紹介した「Beautifl - Flash Gallery of wonderfl」には技術的に新しく取り組んだ箇所があります。それらも今後紹介していきたいと思います。