CSS Grid Layout入門
対応ブラウザが出揃った新しいレイアウト仕様

174
199
200

CSSのGrid Layoutとは、ウェブサイトのレイアウトを構築するための新しい仕様です。今まではウェブサイトのレイアウトを実現するために、floatやFlexboxを使っていた方が多いのではないでしょうか。

Grid Layoutを使えば、HTML要素の構造を汚さず、従来の手法に比べてウェブサイトのレイアウトがつくりやすくなります。たとえばfloatだと親要素にdivを増やす必要があったのが、Grid Layoutを使えばそのようなムダなHTML要素を増やさなくて構わなくなります

今回はレイアウトをつくりながら、Grid Layoutの基礎知識について紹介します。余裕のある方は、記事を読みながら実際に手を動かしてレイアウトをつくってみましょう。

この記事で学べること

  • Grid Layoutの基本的な使い方
  • Grid Layoutの利点
  • サブグリッドの使い方

よくあるレイアウトをつくりながらGrid Layoutの基礎を学ぶ

次のようなヘッダー・メインコンテンツ・左右のサイドバー・フッターがあるレイアウトを例に解説します。

<div class="container">
  <header class="header">header</header>
  <main   class="main"  >main</main>
  <aside  class="aside" >aside</aside>
  <nav    class="nav"   >nav</nav>
  <footer class="footer">footer</footer>
</div>

まずHTMLを書きます。配置する各要素と、それを囲む親要素があります。親要素にはcontainer というクラス名を付けました。

Flexboxで作る場合は

Flexboxを使ってこのレイアウトをつくる場合、横ならびにしたい要素(asidemainnav)をdivなどで囲んでフレックスコンテナーをつくり、横ならびにする要素をフレックスアイテムとして配置します。

わざわざdivを追加する必要があるため、余計な要素が1つ増えますよね。

Grid Layoutで作る場合は

Grid Layoutはレイアウトを囲むコンテナーの要素(例では.containerにその子要素の配置の仕方を指定します。Flexboxと違い、要素を並べる行・列コンテナーとなる要素を用意する必要はありません

Grid Layoutのコンテナーとアイテムについて説明しながらCSSでレイアウトをつくっていきます。

グリッドコンテナー

グリッドレイアウトで要素を配置するためにグリッドコンテナーをつくります。要素に display: grid を指定すると、その要素はグリッドコンテナーになります。(インライン要素として扱うときはdisplay: inline-gridを指定します)

.container {
  display: grid;
}

これだけではまだ要素がただ並んでいるだけです。そこで、グリッドコンテナーにグリッドコンテナーを分割するための指定をします。

グリッドコンテナーを縦・横に分割します。縦方向に分割した各列のサイズはgrid-template-columns 、横方向に分割した各行のサイズはgrid-template-rows で指定します。

列の幅を指定しましょう。今回のレイアウトでは、左のサイドバーの幅が180px、右のサイドバーの幅が160pxです。中央のメインエリアは親要素の幅から左右のサイドバーの幅を引いた可変幅にします。

ここで、メインエリアの幅指定にfrという単位を使います。frはグリッドコンテナーの中を分割するサイズの指定に使える単位です。全体の幅からfr以外の単位(px%など)で指定したものを引き、残りの幅がfrで指定された列に配分されます。Flexboxのflex-growプロパティと同じようなイメージです。今回は、全体の幅から左右サイドバー(180px、160px)の幅を引いた幅をメインエリアに配分したいので次のように書きます。

.container {
  display: grid;
  /* 1列目から順番に180px、1fr、160pxの幅 */
  grid-template-columns: 180px 1fr 160px;
}

同じように各行の高さも指定します。

.container {
  display: grid;
  /* 1列目から順番に180px、1fr、160pxの幅 */
  grid-template-columns: 180px 1fr 160px;
  /* 1行目から順番に60px 1fr 90pxの高さ */
  grid-template-rows: 60px 1fr 90px;
}

このときの列・行のことをグリッドトラックといいます。列・行を分割した線をグリッドラインといいます。グリッドラインは、borderのように見た目上の線ではありません。

グリッドアイテム

グリッドアイテムを配置します。グリッドコンテナー直下の子要素をグリッドアイテムといいます。今回の場合は、ヘッダー・メインコンテンツ・左右のサイドバー・フッターがグリッドアイテムです。

グリッドトラックを分割したグリッドラインは、1本目から順番に1,2,3…と自動的に番号がふられます。grid-column-startgrid-column-endで、グリッドアイテムが列の何本目から何本目のグリッドラインまで配置するか指定します

同じようにgrid-row-startgrid-row-endで行の何本目から何本目のグリッドラインまで配置するか指定します。

.header {
  /* 列の1本目から4本目のグリッドラインまで */
  grid-column-start: 1;
  grid-column-end: 4;
  /* 行の1本目から2本目のグリッドラインまで */
  grid-row-start: 1;
  grid-row-end: 2;
}

このとき、grid-column-endgrid-row-endautoを指定すると、それぞれgrid-column-startgrid-row-startで指定したグリッドラインの次のグリッドラインまでの範囲に配置されます。ヘッダーのgrid-row-endの指定はautoにできます。

.header {
  /* 列の1本目から4本目のグリッドラインまで */
  grid-column-start: 1;
  grid-column-end: 4;
  /* 行の1本目から2本目のグリッドラインまで */
  grid-row-start: 1;
  grid-row-end: auto;
}

同じように他のグリッドアイテムも配置します。

.header {
  /* 列の1本目から4本目のグリッドラインまで */
  grid-column-start: 1;
  grid-column-end: 4;
  /* 行の1本目から2本目のグリッドラインまで */
  grid-row-start: 1;
  grid-row-end: auto;
}

.main {
  /* 列の2本目から3本目のグリッドラインまで */
  grid-column-start: 2;
  grid-column-end: auto;
  /* 行の2本目から3本目のグリッドラインまで */
  grid-row-start: 2;
  grid-row-end: auto;
}

.aside {
  /* 列の1本目から2本目のグリッドラインまで */
  grid-column-start: 1;
  grid-column-end: auto;
  /* 行の2本目から3本目のグリッドラインまで */
  grid-row-start: 2;
  grid-row-end: auto;
}

.nav {
  /* 列の3本目から4本目のグリッドラインまで */
  grid-column-start: 3;
  grid-column-end: auto;
  /* 行の2本目から3本目のグリッドラインまで */
  grid-row-start: 2;
  grid-row-end: auto;
}

.footer {
  /* 列の1本目から4本目のグリッドラインまで */
  grid-column-start: 1;
  grid-column-end: 4;
  /* 行の3本目から4本目のグリッドラインまで */
  grid-row-start: 3;
  grid-row-end: auto;
}

grid-column-startgrid-column-endgrid-columngrid-row-startgrid-row-endgrid-rowという略式プロパティで指定できます。このとき、autoは省略できます。今回の .headerはこのように略式プロパティで書き換えることができます。

.header {
  /* 列の1本目から4本目のグリッドラインまで */
  grid-column: 1 / 4;
  /* 行の1本目から2本目のグリッドラインまで */
  grid-row: 1;
}

これでレイアウトは完成です。以下のサンプルでコードと表示を確認してみてください。

タイル状のレイアウトをGrid Layoutで

タイルが並ぶように同じ幅のアイテムが繰り返し配置されるレイアウトをGrid Layoutでつくってみます。

このようなレイアウトは、floatやFlexboxでもつくることができますがGrid Layoutを使うことで便利になったポイントを紹介します(今回紹介していないプロパティも使っています)。このサンプルでは、Grid Layoutに関するCSSはグリッドコンテナーのみに指定しており、少ないプロパティでこのレイアウトをつくることができました。

.container {
  /* グリッドコンテナ */
  display: grid;
  /* 最小100px、最大1frの列を繰り返しつくる */
  grid-template-columns: repeat(
    auto-fill,
    minmax(100px, 1fr)
  );
  column-gap: 10px;
  row-gap: 10px;
}

レイアウトに関する指定をグリッドコンテナーにまとめられる!

まず1つ目に、グリッドコンテナーの指定のみでこのレイアウトをつくれるのはとても便利です。floatやFlexboxでレイアウトするとき、親要素にコンテナーとなる指定をして、横ならびにするアイテムにはアイテムの幅や余白の指定をする必要があったと思います。Grid Layoutでは、グリッドコンテナーにグリッドアイテムの配置についての指定ができます。

アイテム間の余白調整が手軽

2つ目はrow(column)-gapでグリッドアイテム間の余白を指定していることです。row(column)-gapは、グリッドアイテムの間にだけ余白ができるようになっています。

floatやFlexboxでこのレイアウトをするには、余白の処理に工夫をする必要があります(例:marginをつけて、レイアウトの端等の不要なmarginをネガティブマージンやE:nth-child(n)で消す)。gapを使えば、そういった調整は必要はありません。

親要素が可変幅でもアイテムのサイズ調整がシンプル

3つ目はgrid-template-columns の値、repeat(auto-fill, minmax(100px, 1fr))です。これは、グリッドトラックのサイズの指定に使えるrepeat()auto-fillを使って親要素におさまるようにアイテムを繰り返し横ならびにし、minmaxでアイテムの最小幅・最大幅を指定しています。

floatやFlexboxの横並びレイアウトではレスポンシブ対応をするとき、表示の幅によって各列にいくつのアイテムが並ぶように、どんな幅にするかという指定を複数のプロパティでする必要がありました。Grid Layoutのrepeatauto-fillminmaxをうまく使うと、可変幅レイアウトの調整がしやすくなると思います。

ブラウザの実装

Can I use…によると、Grid Layoutの各ブラウザの対応状況を確認すると、Chrome、Firefox、Safari、Edgeの最新バージョンで利用可能と記載されています。

以前はInternet Expolorer 11向けに、ベンダープレフィックス-ms-gridをつけることで対応していましたが、IE11はすでに公式にサポートを終了していますので、気にする必要はありません。

サブグリッド

CSS Gridにはサブグリッドという機能があります。通常のCSS Gridだと直下の要素しかグリッドアイテムとして認識されません。Gridを親子でそれぞれ繰り返し指定すればグリッドの入れ子ができますが、親子のグリッドは連動しません。

サブグリッドを使うと、グリッドの入れ子ができ、親子のグリッドが連動します

具体的には以下の挙動を確認するとわかりやすいでしょう。

1カラム内には、サムネイル・タイトル・概要文・リンクを配置しています。それぞれのカラムでは文字量が異なりますが、サブグリッドの効用によって、高さが揃っていることが確認できます。

以下はサブグリッドの抜粋です。子要素にdisplay: grid;を指定したうえで、grid-template-rows: subgrid;を指定していることがポイントです。

.container {
  /* グリッドコンテナ */
  display: grid;
  /* 最小256px、最大1frの列を繰り返しつくる */
  grid-template-columns: repeat(auto-fill, minmax(256px, 1fr));
  /* 余白 */
  gap: 16px;
}

.item {
  display: grid;
  grid-row: span 4;
  grid-template-rows: subgrid; /* サブグリッド */
}

Grid Layoutのサブグリッドは、Safari 16.0(2022年9月)、Firefox 71(2019年12月)でサポートされています。

終わりに

今回はGrid Layoutの基本的なレイアウトの作り方と、プロパティを紹介しました。グリッドレイアウトで実現可能なことは他にもたくさんあります。

続編記事「特徴で使い分けたいCSSレイアウト手法」では、Grid LayoutとfloatとFlexboxとの違いについて紹介します。あわせてご覧くださいませ。

※この記事が公開されたのは5年前ですが、 今年9月に内容をメンテナンスしています。

174
199
200