レイアウト手法の新しい武器になるCSSグリッドレイアウト入門

フロントエンドエンジニア

小山 樹人

投稿日: 2024.04.01

更新日: 2024.04.02

  • フロントエンド

CSSのグリッドレイアウトが、主要ブラウザーで利用可能になってからしばらく経ちました。しかし、floatやFlexboxなど従来の手法で目的のレイアウトが実現できることも多く、あまり活用できていないケースもあるのではないでしょうか。筆者自身も、まだまだその使いどころに迷うことが多いです。

この記事では、CSSグリッドレイアウトの基本的な使い方を図版を交えて紹介します。基本のプロパティを整理し、実際のレイアウトでどのように活用できるのか見ていきたいと思います。

CSSグリッドが得意なレイアウト

グリッドレイアウトは、格子状のグリッドを使用して要素の配置をコントロールするレイアウトシステムです。

デザインの上に重ねられた12列のグリッド。
引用:https://developer.mozilla.org/ja/docs/Learn/CSS/CSS_layout/Grids

上図のように、複数の行と列を使って柔軟なレイアウトを構築することが可能です。異なるビューポートサイズに応じてレイアウトを大きく切り替えるような、レスポンシブウェブデザインにも適しています。

フレックスボックスとの違い

フレックスボックスは、要素を行と列のいずれかの方向にレイアウトしやすいように設計されています。それに対して、グリッドレイアウトは行と列に要素を並べます。フレックスボックスによる1次元のレイアウト手法と比較して、グリッドレイアウトは2次元のレイアウト手法であると考えられます。

1次元のレイアウトと2次元のレイアウト図

それぞれ、どのようなレイアウトに向いているか一概に言うことは難しいですが、1次元的であるか2次元的であるかを意識することで、ある程度使い分けの目安になるはずです。

ブラウザーの実装状況

グリッドレイアウトの各ブラウザーの実装状況を確認すると、Chrome、Edge、Safari、Firefoxの最新バージョンでいずれも利用可能となっています。

ブラウザーの実装状況を「Can I use」で確認したスクリーンショット

グリッドレイアウトの構成要素

最初に、グリッドレイアウトに登場する構成要素と名称について、どのようなものがあるか整理します。

  • グリッドコンテナ:グリッドを構成する要素。
  • グリッドアイテム:グリッドコンテナに配置する子要素。
  • グリッドライン:グリッドを構成する縦横の線。
  • グリッドトラック:グリッドの各行と列。
  • グリッドセル:グリッドアイテムを配置するスペースの最小単位。
  • グリッドエリア:複数のセルから構成させる範囲。

グリッドコンテナと呼ばれる格子状の入れ物を用意し、その中に子要素としてグリッドアイテムを配置していきます。

グリッドコンテナとグリッドアイテムの図

グリッドコンテナ内では、縦横のグリッドラインでグリッドを構成します。各行と列をグリッドトラックと呼びます。

グリッドラインとグリッドトラックの図

グリッドアイテムを配置するスペースの最小単位がグリッドセルで、グリッドエリアは1つ以上のグリッドセルから構成されるスペースです。

グリッドセルとグリッドエリアの図

グリッドの作成

構成要素が確認できたので、ここから実際にグリッドを作成していきます。

まず、グリッドコンテナとなる要素のdisplayプロパティの値をgridに指定します(インライン要素として扱う際はinline-grid)。これでコンテナ内の要素がグリッドアイテムとして扱われるようになります。グリッドトラックのサイズを指定するには、列の指定を行うgrid-template-columnsと行の指定を行うgrid-template-rowsプロパティを使用します。

HTML
<div class="grid-container">
  <div class="item-1">1</div>
  <div class="item-2">2</div>
  <div class="item-3">3</div>
  <div class="item-4">4</div>
  <div class="item-5">5</div>
</div>
CSS
.grid-container {
  display: grid;
  grid-template-columns: 100px 150px 50px;
  grid-template-rows: 100px 50px;
}

これで以下のようなグリッドが作成され、各セル内にグリッドアイテムが配置されます。(グリッド関連以外のスタイルは省略しています)。

グリッドのセル内にグリッドアイテムを配置した図

グリッドトラックのサイズ指定

グリッドトラックのサイズ指定には、px単位などに加えていくつかの特別な単位や指定方法も利用できます。

fr単位

fr単位は、トラックサイズをグリッドコンテナのサイズに対しての比率で指定する単位です。例えば、1列目、2列目、3列目を「2:3:1」の比率、1行目と2行目を「2:1」の比率で配置する場合、以下のような指定となります。

CSS
.grid-container {
  display: grid;
  grid-template-columns: 2fr 3fr 1fr;
  grid-template-rows: 2fr 1fr;
}
fr単位によってトラックサイズを割り振った図

通常のpx単位などと混ぜても使えます。例えば、1列目を100pxで固定とし、残りのスペースで2列目3列目を「2:1」の比率で配置するといったことが可能です。

CSS
.grid-container {
  display: grid;
  grid-template-columns: 100px 2fr 1fr;
  grid-template-rows: 2fr 1fr;
}
fr単位とpx単位を同時に使用した際の図

minmax()

トラックサイズの最小値と最大値を指定するにはminmax()を利用できます。次の例では、列を通常「1:1:2」の比率で配置し、1列目は100px以下にならないように制御しています。

CSS
.grid-container {
  display: grid;
  grid-template-columns: minmax(100px, 1fr) 1fr 2fr;
  grid-template-rows: 2fr 1fr;
}
minmax()を使用してトラックサイズを指定した図

repeat()

同じパターンの指定を繰り返すときは、repeat()を利用できます。例えば2fr 2fr 1frの列と100px 100pxの行を構成するのに、以下のような指定が可能です。

CSS
.grid-container {
  display: grid;
  grid-template-columns: repeat(2, 2fr) 1fr;
  grid-template-rows: repeat(2, 100px);
}
repeat()を使用してトラックサイズを指定した図

その他にもauto、min-content、max-content、fit-contentといった値を組み合わせることで、コンテンツに合わせて柔軟にサイズ指定することが可能です。

参考:https://developer.mozilla.org/ja/docs/Web/CSS/grid-auto-columns#値

ポイントまとめ

  • グリッドコンテナとなる要素に対してdisplay: gridinline-grid)を指定する。
  • grid-template-columnsgrid-template-rowsでグリッドトラックのサイズを指定する。
  • トラックサイズの指定には、コンテナのサイズに対しての比率で指定するfr単位や最小値と最大値を指定するminmax()、同じパターンの指定を繰り返すrepeat()などさまざまな単位や値を利用することができる。

グリッドアイテムの配置

ここまでの例では、グリッドアイテムはグリッドトラック内に自動配置されていました。グリッドアイテムの配置位置をコントロールするためには、いくつかの方法が用意されています。

ラインによる配置先の指定

まず1つは、ラインによる配置先の指定方法があります。グリッドを作成すると自動的にグリッドラインに番号が割り振られます。このライン番号を利用してグリッドアイテムの配置先を指定できます。

列のラインは左から右に、行のラインは上から下に向かって番号が振られます。逆方向には負の番号が振られ、どちらで指定することも可能です。

グリッドラインにライン番号を表示した図

列の配置先の指定には、grid-column-startgrid-column-endプロパティを使用し、この2つのプロパティを一括指定するgrid-columnプロパティも利用できます。同様に、行の配置先はgrid-row-startgrid-row-endの各プロパティを使用し、grid-rowプロパティで一括指定が可能です。例えば、グッリッドアイテムを行のライン1~2、列のライン2~4の中に配置するには以下のように指定します。

CSS
.item-1 {
  grid-column-start: 2;
  grid-column-end: 4;
  grid-row-start: 1;
  grid-row-end: 2;
}

/* 一括指定プロパティでまとめて指定した場合 */
.item-1 {
  grid-column: 2 / 4;
  grid-row: 1 / 2;
}
グリッドラインによる指定でグリッドアイテムを配置した図

ラインには任意で名前をつけることも可能です。ライン名はgrid-template-columnsgrid-template-rowsでトラックを設定する際に[]を使って指定します。ライン名はスペースで区切って複数指定することも可能です。また、便利な使い方として、ライン名を「**-start / **-end」といった名前にしておくと、「**」と書くだけで指定できます。

CSS
.grid-container {
  display: grid;
  grid-template-columns: 100px [first-start] 150px 50px [first-end];
  grid-template-rows: [first-start] 100px [first-end] 50px;
}

.item-1 {
  grid-column: first-start / first-end;
  grid-row: first-start / first-end;
}

/* 以下のようにも省略可能 */
.item-1 {
  grid-column: first;
  grid-row: first;
}
グリッドラインの名前を表示した図

エリアによる配置先の指定

ラインによる指定の他に、グリッドにエリアを設定し配置先を指定する方法があります。

エリアの設定にはgrid-template-areasプロパティを使用し、アスキーアートのような書式で各セルに名前を指定します。同名のセルは同じエリアとして扱われ、例えば以下のように指定できます。

CSS
.grid-container {
  display: grid;
  grid-template-areas:
    "area1 area2 area3"
    "area1 area4 area4";
  grid-template-columns: 100px 150px 50px;
  grid-template-rows: 100px 50px;
}
グリッドをグリッドエリアに分割した図

各グリッドアイテムにgrid-areaプロパティを指定することで、該当のエリアに配置できます。

HTML
<div class="grid-container">
  <div class="item-1">1</div>
  <div class="item-2">2</div>
  <div class="item-3">3</div>
  <div class="item-4">4</div>
</div>
CSS
.item-1 {
  grid-area: area1;
}
.item-2 {
  grid-area: area2;
}
.item-3 {
  grid-area: area3;
}
.item-4 {
  grid-area: area4;
}
グリッドエリアにグリッドアイテムを配置した図

また、エリアとトラックサイズの指定には一括指定プロパティのgrid-templateを利用することで、まとめて指定することも可能です。エリアの行ごとにトラックサイズを記述し、列のトラックサイズは/で区切って最後に記述します。

CSS
.grid-container {
  display: grid;
  grid-template:
    "area1 area2 area3" 100px
    "area1 area4 area4" 50px
    / 100px 150px 50px;
}

上記のように、グリッドレイアウトでは同様の指定に対して複数の記述方法が用意されていることが多いです。どの記述方法が良いかは好みの問題も大きいですが、プロジェクト内である程度統一されていると良さそうです。

ポイントまとめ

  • グリッドアイテムの配置方法はラインによる指定と、エリアによる指定がある。
  • ライン番号は自動で割り振られ、別途ライン名を指定することもできる。
  • ラインによる配置先の指定には、grid-column-start grid-column-end grid-column grid-row-start grid-row-end grid-rowの各プロパティを使用する。
  • grid-templage-areasプロパティを使用すると、各セルにエリア名を指定し、grid-areaプロパティでアイテムを各エリアに配置することができる。
  • エリアとトラックサイズの指定には一括指定プロパティのgrid-templateが利用できる。

レイアウトの調整

グリッドアイテムの間隔

グリッドアイテムの間隔の指定には、列の間隔を指定するcolumn-gapと行の間隔を指定するrow-gapの各プロパティを使用します。またそれらを一括で指定するgapプロパティも利用できます。

CSS
.grid-container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(2, 100px);
  row-gap: 8px;
  column-gap: 16px;
}

/* 一括指定プロパティで指定 */
.grid-container {
  gap: 8px 16px;
  /* 列と行の間隔が同じ場合は以下のようにも指定できる */
  gap: 8px;
}
グリッドにgapを追加し表示した図

グリッドの位置揃え

グリッドコンテナ内でトラックの配置位置を指定するにはjustify-contentaligin-contentを使用します。

CSS
.grid-container {
  display: grid;
  grid-template-columns: repeat(2, 100px) minmax(100px, auto);
  grid-template-rows: repeat(2, 100px);
  justify-content: start; /* 左寄せで表示 */
  align-content: center; /* 天地センターに表示 */
}

使用できる値は主に以下のようなものがあります。

  • start:コンテナの先頭側の端に向けて寄せて配置。
  • end:コンテナの末尾側の端に向けて寄せて配置。
  • center:コンテナの中央に寄せて配置。
  • space-between:トラック間に均等にスペースを入れて配置。
  • space-around:トラック間に均等にスペースを入れ、外側にその半分のスペースを入れて配置。
  • space-evenly:トラック間と外側に均等にスペースを入れて配置。
  • stretch:サイズが auto なトラックがあれば余りのスペースを割り振る。

justify-contentに各値を指定した際のレイアウトを図にまとめると、のようになります。

justify-contentの値によって、表示が変更される様子を説明した図

また、この2つのプロパティをまとめて指定するplace-contentプロパティも利用できます。例えばplace-content: centerと指定すると、コンテナ内の上下左右センターに配置することが可能です。

CSS
.grid-container {
  display: grid;
  grid-template-columns: repeat(2, 100px) minmax(100px, auto);
  grid-template-rows: repeat(2, 100px);
  gap: 8px;
  place-content: center;
}
「place-content: center」とした際の表示を表した図

グリッドアイテムの位置揃え

トラック内に配置されたグリッドアイテムの位置揃えには、横方向を制御するjustify-selfと縦方向を制御するalign-selfを使用します。使用できる値は主に以下のようなものがあります。

  • start:コンテナの開始側に向かって詰めて配置。
  • end:コンテナの終了側に向かって詰めて配置。
  • center:コンテナの中央に詰めて配置。
  • baseline:ベースラインで揃えて配置。
  • stretch:4辺をトラックに揃えて配置。

例として、各グリッドアイテムに対してjustify-selfの値を指定すると、画像のような表示となります。

HTML
<div class="grid-container">
  <div class="item-1">1</div>
  <div class="item-2">2</div>
  <div class="item-3">3</div>
  <div class="item-4">4</div>
</div>
CSS
.grid-container {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  grid-template-rows: repeat(2, 100px);
}

.item-1 {
  justify-self: start;
}
.item-2 {
  justify-self: end;
}
.item-3 {
  justify-self: center;
}
.item-4 {
  justify-self: stretch;
}
justify-selfの値によって、表示が変更される様子を説明した図

また、コンテナ側でこれらの値をまとめて指定するためには、justify-itemsalign-itemsを使用できます。さらにこの2つのプロパティの一括指定にはplace-itemsプロパティが利用できます。

CSS
.grid-container {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  grid-template-rows: repeat(2, 100px);
  justify-items: center; /* コンテナ内の全ての横方向の位置揃えをセンターに */
  align-items: center; /* コンテナ内の全ての縦方向の位置揃えをセンターに */
}

/* place-itemsを使用した場合 */
.grid-container {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  grid-template-rows: repeat(2, 100px);
  place-items: center; /* justify-itemsとalign-itemsを同時に指定 */
}

上記どちらの記述でも、以下のように天地左右センターの配置となります。

「place-items: center」とした際の表示を説明する図

ポイントまとめ

  • グリッドアイテム同士の間隔の指定にはcolumn-gaprow-gapプロパティ、またはそれらを一括指定するgapプロパティを使用する。
  • グリッドコンテナ内のトラックの配置位置の指定にはjustify-contentaligin-contentプロパティ、またはそれらを一括指定するplace-contentプロパティを使用する。
  • トラック内に配置されたグリッドアイテムの配置位置の指定にはjustify-selfalign-selfプロパティを使用する。
  • グリッドアイテムの位置揃えをコンテナ側で指定するには、justify-itemsalign-itemsプロパティ、またはそれらを一括指定するplace-itemsプロパティを使用する。

実践グリッドレイアウト:レスポンシブなボタンUI

ここまで、グリッドレイアウトに関する基本的なプロパティの使用方法を見てきました。最後に少し具体的な利用例を考えてみたいと思います。

cho-menの記事の末尾には、記事をシェアするためのボタンUIが配置されています。このUIは、画面幅に応じて伸縮し、一定幅でカラム落ちする仕様となっています。

記事のシェアボタンのUIのスクリーンショット。画面幅に応じた表示が表されている。

シンプルなUIですが、カラム落ちした際に列ごとの幅を揃える処理など意外と考慮事項が多いです。フレックスボックスを利用したり、他のレイアウト方法でも実現可能そうですが、グリッドを使用すると比較的簡単に実装できます。

必要な要件を整理すると以下のようになります。

  • 各ボタンのサイズは均一とする。
  • 画面幅に合わせて伸縮する。
  • 要素間のスペースは一定。
  • 各ボタンが一定のサイズ以下になるとカラム落ちする。

HTMLを用意し、グリッドコンテナ内にボタン要素を配置します。各ボタンの最小幅を150pxとしたい場合、コンテナ側のgrid-template-columnsを以下のように指定することで、要件を満たしたレイアウトが可能となります。アイテム側では幅の指定を特に行っていません。

HTML
<div class="grid-container">
  <button type="button" class="item-1">1</button>
  <button type="button" class="item-2">2</button>
  <button type="button" class="item-3">3</button>
  <button type="button" class="item-4">4</button>
</div>
CSS
.grid-container {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); /* ここがポイント */
  gap: 8px;
}

.item-1 {
  padding: 16px;
  border-radius: 4px;
  border: none;
  background-color: var(--color-red);
}
.item-2 { ... } /* 以下略 */

ポイントはグリッドコンテナに指定した、grid-template-columnsの値です。repeat()の1つめの引数にauto-fitを指定することで、コンテナとトラックの幅に応じて自動で繰り返し回数(列数)が計算されます。2つ目の引数にはminmax(150px, 1fr)を指定し、トラックの最小値を150px、最大値を1frとしています。

指定の「grid-template-columns」によって、画面幅に応じた表示の切り替えを説明した図

CSSグリッドの使用用途として、ページ全体など大きな単位でのレイアウトが考えられます。しかし、使い方次第ではこのような小さなUI内でも、便利に利用できます。さまざまな箇所で、グリッドが利用できないか考えてみると、レイアウトの楽しみが広がるのではないでしょうか。

グリッドをレイアウト手法の引き出しに

本記事では、CSSグリッドレイアウトに必要な基本プロパティの使い方をまとめました。今回紹介したもの以外にも、グリッドを入れ子にして親子のグリッドを連動させるサブグリッドの機能など、まだまだ便利な機能が存在します。従来の方法では実装難易度の高かったレイアウトも、グリッドを使用することで簡単に実現できる場合があります。ぜひ、レイアウト手法の引き出しのひとつとして、CSSグリッドを活用してみてください。

参考資料

ウェブのお悩み、世路庵にご相談ください

ウェブ制作会社には、「言ったことしかやってくれない」「提案がない」といった不満を抱かれるケースがあります。目を引くようなビジュアルは作れるがビジネス理解が不足している、運用はしてもらえるがデザインやコーディングは外注に丸投げしている、といった体制では、しばしばプロジェクトが袋小路に迷い込んでしまいます。

世路庵は、ビジネスとクリエイティブを両立するウェブ制作会社です。ウェブサイトやウェブアプリケーションに課題を感じている方は、創業16年以上の経験と、業種・業態を選ばない800件以上の実績を持つ世路庵をぜひご検討ください。

合同会社世路庵

記事をシェアする

小山 樹人

フロントエンドエンジニア

静岡県出身。大学卒業後、桑沢デザイン研究所の夜間部でグラフィックデザインを学ぶ。専門誌や教育系の出版物を中心に、約10年間DTP制作の仕事に携わる。Webのフロントエンド開発の分野に興味を持ち、2023年に世路庵に入社。 デザインと開発の両面からものづくりに携わっていきたい。