CSSのGrid Layoutとは、ウェブサイトのレイアウトを構築するための仕様です。今まではウェブサイトのレイアウトを実現するために、floatやFlexboxを使っていた方が多いのではないでしょうか。
Grid Layoutを使えば、HTML要素の構造を汚さず、従来の手法に比べてウェブサイトのレイアウトがつくりやすくなります。特に、Flexboxではつくるのが難しい、縦軸・横軸がある格子状のレイアウトに向いています。
今回はレイアウトをつくりながら、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を使ってこのレイアウトをつくる場合、横ならびにしたい要素(aside
、main
、nav
)を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-start
とgrid-column-end
で、グリッドアイテムが列の何本目から何本目のグリッドラインまで配置するか指定します。
同じようにgrid-row-start
とgrid-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-end
・grid-row-end
にauto
を指定すると、それぞれgrid-column-start
やgrid-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-start
とgrid-column-end
はgrid-column
、grid-row-start
とgrid-row-end
はgrid-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のrepeat
やauto-fill
、minmax
をうまく使うと、可変幅レイアウトの調整がしやすくなると思います。
サブグリッド
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は2017年10月以降リリースのChrome、Firefox、Safari、Edge含む主要なブラウザで利用可能です。
サブグリッドは実装状況にばらつきがありましたが、2023年9月にChrome、Edgeが対応したことで、Chrome、Firefox、Safari、Edge含む主要なブラウザで利用可能となりました。
終わりに
今回はGrid Layoutの基本的なレイアウトの作り方と、プロパティを紹介しました。グリッドレイアウトで実現可能なことは他にもたくさんあります。
続編記事『特徴で使い分けたいCSSレイアウト手法』では、Grid LayoutとfloatとFlexboxとの違いについて紹介します。あわせてご覧くださいませ。
※この記事が公開されたのは7年前ですが、半年前の4月に内容をメンテナンスしています。