ふわっと学ぶ CSS Grid

2019.11.20

なち
2次元レイアウトをHTML/CSSで操作するCSSの機能であるCSS Gridについて、ふわっと学んでみましょう。

目次

  1. はじめに
  2. CSS Gridを適用するデザイン
  3. CSS Gridの導入
  4. CSS Gridの応用(ノングリッドデザイン)
  5. まとめ

1. はじめに

CSS Grid Layoutは2次元レイアウトをHTML/CSSで操作するCSSの機能のことです。格子状のマス目に好きな位置に要素を配置したり、結合したりすることで様々なレイアウトを実現することができます。

CSS Gridをについて調べ始めたとき、これまでのfloatやflex-box、tableタグとの違いがあまりピンときませんでした。 CSS Gridを使用しなくても実現できるデザインしか思い浮かべることができず、どうしてCSS Gridが注目されるようになってきたのかがわからなかったのです。 そんなとき、こちらの記事に辿り着きました。

「ボックスを敷き詰めるレイアウトからの解放」

この文章を見た瞬間、ハッとしました。 私の頭の中は敷き詰めるレイアウトに囚われていて、その中でCSS Gridをどう使うかしか考えていなかったことに気づいたのです。この視点に気づいてからは、CSS Gridで実現するデザインのイメージが一気に広がりました。

というわけで、今回はCSS Gridを適用するデザインとCSS Gridの導入についてふわっと学んでいきたいと思います。

2. CSS Gridを適用するデザイン

CSS Gridの用語

具体的な話に入る前にCSS Gridを使用する時に出てくる用語の一部を説明しておきます。

  • コンテナ:グリッド全体を囲む要素。display: grid;またはdisplay: inline-grid;を指定する。
  • アイテム:コンテナ直下の子要素。
  • ライン:グリッドを分ける垂直および水平の線のこと。グリッドの上下左右それぞれの両端にも存在。
    • 上と左からは、1から順に正の番号が振られる。また、下と右からは、-1から順に負の番号が振られる。
  • トラック:グリッドの行および列のこと。
  • セル:アイテムを配置できる最小の単位。
  • エリア:一つあるいは複数のセルが結合してできるセルの集まり。エリアには名前を付けることができ、アイテムを配置できる。 詳しくはこちら

適用するデザイン

CSS Gridはラインを引いて親要素を分割し、そのラインに沿って子要素を配置していきます。つまりラインを引くことができれば、グリッドデザインでもノングリッドデザインでも、CSS Gridを適用することができます。

また、ページ全体を親要素として捉えても良いですし、モジュールごと別々の親要素としても良いです。もちろん、全体と要素が入れ子になっていても問題ありません。ラインが多くなりすぎると数を数えるのが複雑になったり、デザイン変更によってラインが増減した時の対応に時間がかかったりするので、入れ子や部分部分に使うのが現実的だと思います。

CSS Gridは2次元上に自由に配置することができるという特徴があります。HTML上の記述順とブラウザ上の表示順を切り離して考えることができるようになったということです。このため、ノングリッドデザインの場合でもグリッドデザインと同じ文書構造のまま表示時の配置を変えることができます。 ノングリッドデザインもこれまでのグリッドデザインと同様の工数で組めるようになったとなれば、同コストで提案できるwebデザインの広がりにつながるはずです。

CSS Gridを導入するときにエンジニアが必要とする情報は以下の2点です。

  • デザイン上のガイドライン
    • CSS Gridを使用する要素を決める人がガイドラインを引くのが良いです。多くの場合はエンジニアになるかと思います。
    • 画面幅を変更した際に、幅固定の要素と変動する要素がある場合はその部分の指示書をデザイナーさんから頂く必要があります。エンジニアの裁量で良い場合は不要です。
  • 文書構造の情報
    • スマートフォンとPCで要素の位置が変わる場合やノングリッドデザインの場合は、ブラウザに認識させる要素順の資料があると嬉しいです。SEO重視で要素の順番を決めてもらい、CSS Gridで表示順を調整するのが望ましいです。

3. CSS Gridの導入

それでは実際にCSS Gridを導入してみましょう。

対象ブラウザ

  • Can I use...?
  • Chrome、Firefox、Safari、Edgeの最新バージョンで利用可能
  • IE10以上では-ms-のベンダープレフィックス付きでサポート
    • Chrome、Firefox、Safariは「CSS Grid Layout Module Level 1」をもとに実装されているが、IE10以上・Edge15のGrid Layoutは2011年時点の仕様である「Grid Layout | W3C Working Draft 7 April 2011」をもとに実装されているため、対応しているプロパティや仕様に違いがある。

IE10以上・Edge15とその他ブラウザの対応表

CSS Grid Layout Module Level 1 IE10以上・Edge15で実装されているGrid Layout 備考
display: grid display: -ms-grid  
grid-template-rows(columns) -ms-grid-rows(columns)  
grid-row(column)-start -ms-grid-row(column)  
grid-row(column)-end なし グリッドアイテムの配置終了位置を指定するプロパティはなし。-ms-grid-row(column)で対応する。
    -ms-grid-row(column)-span グリッドがまたがる行・列の数を指定する。既定値は1。
align-self -ms-grid-column-align  
jusitify-self -ms-grid-row-align  

Autoprefixer

IE10以上・Edge15の対策をするために毎回両方の記述を使うのは面倒かと思います。 そんな時に便利なのが、Autoprefixer(バージョン8〜)です。grid-template-areasなどIE10以上・Edge15で本来は利用できないプロパティでも、互換性のあるコードに変換してくれます。 gulpを使用している場合、Autoprefixerを使用していることが多いと思うのですが、この機能はデフォルトでは無効になっているため、オプションでgrid: trueと指定して有効化させます。gulpfile.jsでautoprefixerを記述している箇所に追記してください。

gulpfile.jsgulp.task("default", () => {
  return gulp.src("src/style.css")
    .pipe(plugins.autoprefixer({
        // ベンダープレフィックスを自動付与する
        grid: true,
        browsers: ['last 2 version', 'iOS >= 10.0', 'Android >= 4.4']
        }))
    .pipe(gulp.dest("dist"));
});

サンプルを組んでみよう

簡単なサンプルを作成してみましょう。以下のようなデザインを想定しています。

ABCで1つのGridレイアウトになっており、Cの中にさらにGridレイアウトを作ってCAとCBを格納しています。

  • grid-template-rows:行のトラックの高さを半角スペースで区切って指定
  • grid-template-columns:列のトラックの幅を半角スペースで区切って指定
  • grid-row:アイテムが占める行のラインの番号をスラッシュ区切りで指定する(1番上のラインを1とする)
  • grid-column:アイテムが占める列のラインの番号をスラッシュ区切りで指定する(1番左のラインを1とする)
  • fr:単位。fraction(分数)のこと。詳しくはこちら
index.html<div class="m-grid">
    <div class="m-grid-item -itemA">A</div>
    <div class="m-grid-item -itemB">B</div>
    <div class="m-grid-item -itemC">
      <div class="m-grid-item -itemCA">CA</div>
      <div class="m-grid-item -itemCB">CB</div>
    </div>
</div>

今回はSCSS記法を用いたSASSでコード例を記述したいと思います。 SASS: CSSを効率的に書くことができるメタ言語

index.scss.m-grid {
  display: grid;
  grid-template-rows: 190px 108px; // 上から190px、108pxに分ける
  grid-template-columns: 98px 1fr; // 左から98px、残り(可変)に分ける
}
.m-grid-item {
  &.-itemA {
    grid-row: 1 / 3;  // 横ラインの1本目から3本目まで
    grid-column: 1 / 2; // 縦ラインの1本目から2本目まで
    background-color: #e77c8a;
    font-size: 48px;
    text-align: center;
    line-height: 298px;
  }
  &.-itemB {
    grid-row: 1 / 2;
    grid-column: 2 / 3;
    background-color: #4b8daa;
    font-size: 48px;
    text-align: center;
    line-height: 190px;
  }
  &.-itemC {
    grid-row: 2 / 3;
    grid-column: 2 / 3;
    background-color: #3d6e98;
    font-size: 30px;
    // 入れ子部分
    display: grid;
    grid-template-rows: 25px 58px 25px;
    grid-template-columns: 30px 1fr 2fr 30px;
  }
  &.-itemCA {
    grid-row: 2 / 3;
    grid-column: 2 / 3;
    background-color: #cdd2c2;
    font-size: 26px;
    color: #3a3a3a;
    text-align: center;
    line-height: 58px;
  }
  &.-itemCB {
    grid-row: 2 / 3;
    grid-column: 3 / 4;
    background-color: #b2c0b4;
    font-size: 26px;
    color: #3a3a3a;
    text-align: center;
    line-height: 58px;
  }
}

親要素で枠を指定して、子要素をそれぞれの場所に配置していくようなイメージでCSSを記載していきます。 並べるというよりも配置するという感覚がなんとなくわかりましたでしょうか。

4. CSS Gridの応用(ノングリッドデザイン)

基本的な組み方をしてみたので、次はノングリッドデザインを組んでみましょう。 デザインは以下の通りです。

PCではノングリッドデザイン、スマートフォンではグリッドデザインになります。 またA、Bは画像エリアとなっており、PCとスマートフォンで配置場所が異なります。 CSS Gridを使わないで組むことを想定してみると、ちょっとCSSが複雑になりそうな気がしませんか。

CSS Gridを使う場合について順を追って説明します。

ガイドラインを引く

まずはデザインにラインを引きます。今回は以下のようにPhotoshopでガイドラインを引いてみました。

幅、高さを指定

ガイドラインを元にGridの親要素に幅、高さを指定します。 スマートフォンはレスポンシブにするため、%を指定します。今回は高さの部分に変化する場合はautoを、余白は固定値を入れています。

index.html<div class="m-grid"></div>
index.scss.m-grid {
  display: grid;
  grid-template-rows: 30px 38px 29px 49px 21px 149px 64px;
  grid-template-columns: 30px 263px 17px 260px 178px 22px 30px;
}
@media only screen and (max-width: 799px) {
  .m-grid {
    grid-template-rows: 27px auto 12px auto 20px auto 34px;
    grid-template-columns: 5.5% 50% 3% 36% 5.5%;
  }
}

子要素を配置

子要素を配置していきます。

index.html<div class="m-grid">
  <h2 class="m-grid-ttl">TitleTitleTitleTitleTitle</h2>
  <figure class="m-grid-imgA">
    <img src="img/img-A.jpg" alt="">
  </figure>
  <p class="m-grid-txt">texttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttext</p>
  <figure class="m-grid-imgB">
    <img src="img/img-B.jpg" alt="">
  </figure>
</div>
index.scss.m-grid-ttl {
  grid-row: 4 / 5;
  grid-column: 2 / 5;
  font-size: 3.233rem;
  z-index: 2;
  color: #333333;
  line-height: 1;
}
.m-grid-txt {
  grid-row: 5 / 7;
  grid-column: 2 / 3;
  font-size: 1.6rem;
  word-break: break-all;
  color: #333333;
}
.m-grid-imgA {
  grid-row: 3 / 7;
  grid-column: 4 / 6;
  z-index: 1;
}
.m-grid-imgB {
  grid-row: 2 / 6;
  grid-column: 5 / 7;
  z-index: 2;
}
@media only screen and (max-width: 799px) {
  .m-grid-ttl {
    font-size: 5.7vw;
    grid-row: 2 / 3;
    grid-column: 2 / 5;
  }
  .m-grid-txt {
    font-size: 3vw;
    grid-row: 6 / 7;
    grid-column: 2 / 3;
  }
  .m-grid-imgA {
    grid-row: 4 / 5;
    grid-column: 2 / 5;
  }
  .m-grid-imgB {
    grid-row: 6 / 7;
    grid-column: 4 / 5;
  }
}

これでデザインのような配置を実現できるはずです。

ここまで組んでみると並べるではなく、配置するという感覚がなんとなくわかってきたのではないでしょうか。 paddingやmargin、absoluteを使用せずに組んでいたことに、後になって気づきました。CSS Gridは余白の取り方も変えてしまうのだなと思いました。

ノングリッドデザインにCSS Gridを使用してみて、予想通りとても相性が良いことがわかりました。PC/スマートフォンでの配置順が変わっても、悩むことなく配置を変えることができたのも良かったです。

5. まとめ

CSS Gridについて知っていく中で、グリッドデザインの枠にとらわれていた考え方をクルンと変えることができました。 2次元配置についてもわかっていなかったのですが、ノングリッドデザインを組むことでなんとなくつかめてきた気がします。また、ノングリッドデザインや、PC/スマートフォンで配置順が変わるデザインは、CSS Gridと相性が良いということがわかりました。

これまで、いかにグリッドデザインに当てはめてflex-boxやfloatで組んでいくかを考えていたのですが、これからはCSS Gridという選択肢を持って考えていくことができそうです。

長くなってしまいましたが、最後まで読んでいただきありがとうございました。

参考サイト

Neuromagic Labsの新着記事