CSS Grid(display:grid)の使い方

CSS Grid(display:grid)の基本的な使い方について。グリッドの作成(コンテナーやトラックの定義、アイテムの配置)や関連する grid-template や grid-column、grid-row などのプロパティや repeat()、minmax() 関数、新しく導入された fr 単位、暗黙的及び明示的なグリッド、自動配置アルゴリズムなどについての覚書です。

作成日:2020年12月04日

関連ページ:CSS Grid + JavaScript で Masonry レイアウト

CSS Grid レイアウト

CSS Grid(display:grid)を使うと簡単に以下のようなグリッドレイアウトを作成することができます。

サンプル(幅が 40em 以上でグリッドレイアウト)

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CSS Grid Sample</title>
<style>
body {
  width: 95%;
  max-width: 960px;
  margin: 2em auto;
}
.header, .footer, .article, .aside {
  padding: 10px;
}
.header {
  background-color: #CEECF5;
}
.article {
  background-color: #D8F7DE;
}
.aside {
  background-color: #F6F7CC;
}
.footer {
  background-color: #F6C2C3;
}
@media (min-width: 40em) {
  .container {
    display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    gap: 20px;
  }
  .header {
    grid-column: 1 / 13;
    grid-row: 1;
  }
  .article {
    grid-column: 4 / 13;
    grid-row: 2;
  }
  .aside {
    grid-column: 1 / 4;
    grid-row: 2;
  }
  .footer {
    grid-column: 1 / 13;
    grid-row: 3;
  }
}
</style>
</head>
<body>
<div class="container">
  <div class="header">
    <h1>Header</h1>
  </div>
  <div class="article">
    <h2>Article</h2>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dolorum blanditiis incidunt, labore totam consequatur cupiditate! Explicabo beatae, quam, nulla eius voluptatum aspernatur adipisci repellat dolor labore perspiciatis, consectetur unde nobis.</p>
    <p>Vero a fuga aspernatur veniam assumenda explicabo porro error dolores sunt consequatur! Ex, perferendis aspernatur vero distinctio. Dolor itaque repellat hic asperiores aperiam exercitationem, aut labore provident architecto voluptatem excepturi</p>
  </div>
  <div class="aside">
    <h3>Aside</h3>
    <p>Doloribus, asperiores iure dolore necessitatibus ea voluptate, vero voluptates quasi praesentium? Est, molestias? </p>
  </div>
  <div class="footer">
    <h4>Footer</h4>
  </div>
</div>
</body>
</html>

グリッド(Grid)は列と行を定義する水平線と垂直線(グリッドライン)が交差した格子状のもので、要素をグリッド上の行と列の中に配置することができます。

グリッドはグリッド全体を囲む要素のグリッドコンテナーとその中に配置されるグリッドアイテムによって構成されます。

CSS Grid で使われる用語
用語 説明
グリッドコンテナー グリッド全体を囲む要素(グリッドの親要素)。display: grid または display: inline-grid を指定した要素。
グリッドアイテム グリッドコンテナーの中に配置された子要素。グリッドコンテナーを作成すると、すべての直接の子要素がグリッドアイテムとなります。グリッドアイテムは複数のセルにまたがって配置することができます。
グリッドライン グリッドを分割する垂直および水平の線のことで、グリッドの両端にも存在します。グリッドラインは数字によって参照することができ、上または左から番号が振られています(番号は1から始まります)。
グリッドトラック グリッドの行および列(2本のグリッド線の間の空間)のこと。
グリッドセル 四つの交差するグリッドラインに囲まれた領域のこと。グリッドの最小単位。
グリッドエリア 一つ以上のグリッドセルからなるグリッドアイテムを配置する長方形の領域(エリア)。グリッドエリアは必ず長方形の領域となります。T 字型や L 字型のグリッドエリアを作ることはできません。
グリッドギャップ グリッドトラック間の余白(ガター)。

※グリッドコンテナーは単にコンテナー、グリッドアイテムはアイテム、グリッドラインはラインのように省略した呼び方をしている場合があります。

グリッドインスペクター

Firefox の開発ツール「グリッドインスペクター」を使用すると簡単に CSS グリッドレイアウトを調査することができます。

インスペクターで「grid」やグリッドのアイコンをクリックするとグリッドレイアウトがオーバーレイ表示されます。また、右側のグリッドタブの「グリッドをオーバーレイ表示」でも表示を切り替えられ、「グリッドの表示設定」で線番号(ライン)や領域名(エリア)の表示なども切り替えることができます。

以下は12列、3行のグリッドレイアウト(最初のサンプル)の例です。

Chrome では、インスペクターで display: grid を指定した要素にマウスオーバーするとグリッドレイアウトがオーバーレイ表示されます。

追記:現在は Chrome でも同様にグリッドレイアウトを確認できます。

参考:MDN CSS グリッドレイアウト

グリッドの作成

以下がグリッドを作成するおおまかな流れです。

  1. 作成するグリッドの親要素になるコンテナーに display: grid を指定
  2. コンテナーに grid-template-columns で列を、grid-template-rows で行を設定
  3. コンテナーの子要素の各アイテムに位置を指定

自動配置の方向

デフォルトではグリッドにアイテムを配置する際に、列を定義すると定義された列の数よりアイテムが多い場合は自動的に行が追加されていきます。

例えば、3列のグリッドを定義して7つのアイテムがあると最初の3つのアイテムは1行目に配置され、4〜6番目のアイテムは2行目に、7番目のアイテムは3行目に自動的に配置されます。

この挙動は grid-auto-flow プロパティで変更することができます(列の自動配置)。デフォルトの grid-auto-flow の値は row で、必要に応じて自動的に行(row)が追加されます。

サンプルの構成

以下がこの例で使用する初期状態の HTML と CSS です。

グリッド全体を囲むコンテナーとなる container クラスを指定した div 要素の中にアイテムとなる div 要素を配置します。

HTML
<div class="container">
  <div class="item1">item1</div>
  <div class="item2">item2</div>
  <div class="item3">item3</div>
  <div class="item4">item4</div>
  <div class="item5">item5</div>
  <div class="item6">item6</div>
  <div class="item7">item7</div>
</div>

見やすいようにアイテムの要素(コンテナーの子要素)にパディングと背景色、枠線を設定しています。

CSS
.container > div {
  padding: 10px;
  background-color: #D5F9CC;
  border: 1px solid #CCC;
}
item1
item2
item3
item4
item5
item6
item7

グリッドコンテナー

コンテナーとなる要素に display: grid を指定してグリッドを定義します。これによりコンテナーの直接の子要素のすべてがグリッドアイテムになります。

言い換えると、要素に display: grid を指定するとその要素はグリッドのコンテナーになり、その直接の子要素のすべてがグリッドアイテムになります。

.container {
  display: grid;
}

display: grid を宣言すると1列のグリッドが作成されるだけで、アイテムは通常フローのように垂直方向に表示されブラウザー上での見た目は display: grid を指定していない前述の例と変わりはありません。

Firefox のグリッドインスペクターで確認すると、1列のグリッドが作成されてアイテムの数だけ自動的に行が追加されている(暗黙的なグリッドが作成されている)のが確認できます。

グリッドトラック

グリッドのレイアウトを二次元にするには、グリッドの列と行(グリッドトラック)を定義します。

grid-template-columns を使って列(トラック)を、grid-template-rows を使って行(トラック)をグリッド上に定義することができます。

グリッドトラックを定義するプロパティ
プロパティ 説明
grid-template-columns グリッドの列を定義するプロパティ。ライン名と列のトラックのサイズを設定することができます。サイズは任意の長さの単位(px など)やパーセント、auto などのキーワード、新たに導入された fr という単位が使えます。トラックのサイズを半角スペースで区切って指定すると自動的に整数のライン名が設定されますが、[ライン名] のようにブラケットでライン名を明示的に指定することもできます。
grid-template-rows グリッドの行を定義するプロパティ。ライン名と行のトラックのサイズ(px や %、fr、キーワード等)を設定することができます。列と同様、[ライン名] のようにブラケットでライン名を明示的に指定することもできます。

参考:

grid-template-columns

grid-template-columns プロパティでは列(トラック)のサイズのリスト(半角スペース区切り)を指定してグリッドの列トラックを定義することができます。

以下は grid-template-columns を使って 200px 幅の列のトラックを2つ定義する例です。

この例の場合、7つのアイテム(子要素)があるので2列に収まるように4つの行(暗黙的なグリッド)が自動的に作成され、グリッドの各セルにアイテムが1つずつ配置されます。

.container {
  display: grid;
  grid-template-columns: 200px 200px;
}

以下は 200px 幅の列のトラックを3つ定義する例です。この例の場合、7つのアイテムが収まるように自動的に3つの行が作成されます。

.container {
  display: grid;
  grid-template-columns: 200px 200px 200px;
}

行のサイズ(高さ)を設定していないので、高さはコンテンツにあわせて調整されます。

fr 単位(unit)

fr という単位を使用すると柔軟にグリッドのトラック(行と列)のサイズを設定できます。

fr は利用可能なスペースを分数 (fraction)を使って表します。利用可能なスペースとは fr 単位以外で設定された部分(px 等で設定されたスペースを除いた部分)のことです。

fr には分数の分子にあたる値を指定し、分母はそれぞれの fr で指定した値の合計になります。

また、flexible length または <flex> は fr 単位の寸法(長さ)を意味し、fr 単位を使ってサイズを設定したトラックを flexible tracks と呼びます。

参考: w3.org /Flexible Lengths: the fr unit

以下は全体の幅に応じて伸縮する3等分されたトラックを作成する例です。

この場合、fr 単位以外で設定されたトラックはないので利用可能なスペースは幅全体になります。

1fr の幅のトラックを3つ指定しているので、利用可能なスペース全体の幅は 3fr(= 1fr + 1fr + 1fr)になり、各トラックの幅は 1fr なのでぞれぞれ全体の 1/3 の幅になります。

.container {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
}

次の例は、1つの 2fr のトラックと2つの 1fr のトラックを定義しています。

利用可能なスペース(幅)は 2fr + 1fr + 1fr = 4fr で4つに分割され、最初のトラックに 2/4(2fr)が割り当てられ、残りはそれぞれ 1/4(1fr)ずつ割当てられます。

.container {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr;
}

以下は絶対サイズ(px)のトラックと分数単位(fr)を一緒に使用する例です。

最初のトラックは絶対サイズの 400px なので、この値は利用可能なスペース(幅)から除外されます。残りのスペース(全体 - 400px)は3つに分割され、比率に応じてトラックに割り当てられます。

.container {
  display: grid;
  grid-template-columns: 400px 1fr 2fr;
}

利用可能なスペースは fr 以外で指定されたスペースを除外した値として算出されます。

以下の場合、利用可能なスペース(幅)は全体の幅から 400px(150 + 250)を引いた値になります。

.container {
  display: grid;
  grid-template-columns: 1fr 150px 2fr 250px;
}

全体の幅が 820px の場合、1列目は 420px(820 - 400)の3分の1の 140px、3列目は3分の2の 280px になります。

auto キーワード

auto はコンテンツに合わせて(内容に基づいて)トラックのサイズを自動的に調整します。

auto キーワードは指定する条件によっては fr 単位と似ていますが、fr はコンテナー(親要素)のサイズに合わせてサイズを調整するのに対し、auto はコンテンツのサイズ(内容)に合わせてトラックのサイズを調整します。

auto は同じ列または行に fr がなく、auto を1つだけ指定する場合は 1fr と同じように動作します。

以下の場合、100px と 200px の列と残りを埋める auto の列が作成されます。

.container {
  display: grid;
  grid-template-columns: 100px 200px auto;
}

上記は以下のように auto の代わりに 1fr を指定した場合でも同じ表示になります。

.container {
  display: grid;
  grid-template-columns: 100px 200px 1fr;
}

以下の場合、全てのトラックのコンテンツが十分に小さければ(fr で分割した場合の幅より小さければ)どちらも同じような表示になりますが、auto はコンテンツにあわせて調整されるので一定以上の大きさになると表示が異なってきます。

.container {
  display: grid;
  grid-template-columns: auto auto auto;
}
.container {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
}

以下は1つのトラックのコンテンツの文字が多い場合の auto auto auto の動作です。

以下は上記と同じコンテンツでの 1fr 1fr 1fr での動作です。コンテンツに関わらず利用可能なスペースを均等に割り当てています。

以下のような場合でも auto と fr の動作が異なります。

以下の2つの auto はそれぞれのコンテンツによりサイズが調整されます。

.container {
  display: grid;
  grid-template-columns: 100px auto auto;
}

以下の2つの 1fr は全体の幅から100pxを除外した利用可能なスペースを均等に割り当てられます。

.container {
  display: grid;
  grid-template-columns: 100px 1fr 1fr;
}

また、auto と fr を一緒に使う場合も動作が異なります。

以下は3列目を auto にした場合です。

auto を指定した3列目のトラックが、コンテンツ(内容)の文字に合わせたサイズになって、残りの利用可能なスペースが2つの 1fr に割当てられます。

.container {
  display: grid;
  grid-template-columns: 1fr 1fr auto;
}

3列目のコンテンツが大きければ、以下のようになります。

repeat() 関数

CSS 関数の repeat() を使用して、トラックのリストのすべてまたは一部を繰り返すことができます。

以下が repeat() のおおまかな書式です。

repeat( [ 繰り返し回数 | auto-fill | auto-fit ] , トラックサイズ(のリスト) )

repeat() 関数は CSS グリッドの grid-template-columns と grid-template-rows プロパティの中で使うことができます。

参考:MDN repeat() / w3.org auto-repeat
説明
auto-fill auto-fill を指定すると繰り返しの数は、グリッドコンテナーをオーバーフローさせない最大の正の数になります。スペースが余り列トラックのサイズより大きい場合は、空のトラックが作成(追加)されます。
auto-fit auto-fill と同様に動作しますが、グリッドアイテムを配置した後、空の繰り返しトラックが折りたたまれる点が異なります。スペースが余る場合は各列トラックの幅を大きくしてスペースを埋め尽くします。

関連:repeat() を使った便利なパターン

以下のグリッド定義は

.container {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
}

以下のように記述することができます。

.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
}

repeat() はトラックリストの一部にも使えます。以下は最初に 200px のトラックを持ち、続けて3つの 1fr トラック、最後に 100px のトラックを持つグリッドを作成します。

.container {
  display: grid;
  grid-template-columns: 200px repeat(3, 1fr) 100px;
}

repeat() はトラックリストも引数に取るので、トラックリストの繰り返しパターンを作成できます。

以下の場合は 1fr と 2fr から成るトラックのパターンを3回繰り返した6つのトラックで構成さたグリッドになります。

.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr 2fr);
}

auto-fill

繰り返し回数に auto-fill を指定すると、グリッドコンテナーをオーバーフローさせない最大の数のトラックが作成されます。

以下の場合、100px 幅の列のトラックがオーバーフローしない数だけ作成されます。

.container {
  display: grid;
  grid-template-columns: repeat(auto-fill, 100px);
}

以下は上記の場合のブラウザの幅が 830px の例で、8つの列のトラックが作成されます。

※この例では body 要素に max-width: 960px を指定してあります。

以下はブラウザの幅が 530px の例で、5つの列のトラックが作成されます。

auto-fit

繰り返し回数に auto-fit を指定すると auto-fill と同様に動作しますが、グリッドアイテムを配置した後、空の繰り返しトラックが作成されません(空の繰り返しトラックは折りたたまれます)。

.container {
  display: grid;
  grid-template-columns: repeat(auto-fit, 100px);
}

以下は上記の場合のブラウザの幅が 830px の例です。アイテムが7つしかないので、7つの列のトラックが作成され、auto-fill とは異なり余ったスペースには空のトラックは作成されません。以下の場合、8つ目の空のトラックは折りたたまれ、ライン9はライン8に重なっています。

※この例では body 要素に max-width: 960px を指定してあります。

grid-auto-rows / grid-auto-columns

暗黙的なグリッド

定義されたグリッドの外側に何かを配置した場合、グリッドは暗黙的なグリッドに行と列を作成します。

ここまでの例では grid-template-columns を使って列トラックのみを定義しましたが、その際に全てのアイテムを配置するために(ブラウザににより)自動的に行が作成され暗黙的なグリッドが作成されていました(参考:CSS グリッドレイアウトでの自動配置)。

暗黙的なグリッドはブラウザにより自動的にアイテムがそのグリッドの外側、例えば新しい行に配置されたときに作成されるグリッドのことです。もし、grid-template-columns を使って3列のトラックのみを定義した場合、4つ目以降のアイテムはブラウザにより行が自動的に追加されグリッドが作成され配置されます。

明示的なグリッドは、grid-template-columns や grid-template-rows で定義された(自ら定義した)行と列から構成されるグリッドのことです。

暗黙的なグリッドのトラックにサイズを指定する場合は、grid-auto-rows と grid-auto-columns プロパティを使用します。

デフォルトでは、暗黙的なグリッドに作成されたトラックは auto でサイズ調整されます。

プロパティ 説明
grid-auto-rows 暗黙的なグリッドの行トラックにサイズを指定
grid-auto-columns 暗黙的なグリッドの列トラックにサイズを指定

以下は grid-auto-rows を使用して暗黙的なグリッド内に作成されたトラックが 80px の高さになるように設定する例です。

.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: 80px;
}

列の自動配置

デフォルトでは明示的に定義した列と行にアイテムが収まらない場合は自動的に行が追加されますが、grid-auto-flow プロパティの値に column を指定することで列を自動的に追加することができます。

この場合、grid-template-rows で定義した行にアイテムを上から(垂直方向に)配置し、定義された行がいっぱいになれば次の列へ配置します。

明示的に列が定義されていない場合は、ブラウザは必要に応じて自動的に列を追加します(暗黙的なグリッドを作成します)。自動的に作成される列のサイズは grid-auto-columns プロパティを使って指定することができます。

以下は高さ150pxの3つの行トラックを持つグリッドを作成する例です。

アイテムは行方向(垂直方向)に配置され、3行を満たすと列が追加されアイテムは上の行から順番に配置されます。

.container {
  display: grid;
  grid-template-rows: repeat(3, 150px);  /* 高さ150pxの3つの行トラックを定義 */
  grid-auto-flow: column; /* 自動配置の方向を行方向へ */
}

この例の場合、7つのアイテムがあるので3列のグリッドが作成されます。

以下は grid-auto-columns で自動的に生成される列のサイズを 300px 100px に指定する例です。

.container {
  display: grid;
  grid-template-rows: repeat(3, 150px);
  grid-auto-flow: column;
  grid-auto-columns: 300px 100px; /* 自動的に生成される列のサイズ指定 */
}

2つの行トラックを持つグリッドに変更すると、7つのアイテムを配置できるように4列のグリッドが作成されます。

.container {
  display: grid;
  grid-template-rows: repeat(2, 150px); /* 2行のグリッドに変更 */
  grid-auto-flow: column;
  grid-auto-columns: 300px 100px;
}

参考:CSS グリッドレイアウトでの自動配置

grid-template-rows

grid-template-rows プロパティでは行(トラック)のサイズのリスト(半角スペース区切り)を指定してグリッドの行のサイズを設定することができます。

以下は1行目から順番に100px 50px 50pxの高さの行を設定する例です。

.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: 100px 50px 50px;
}

上記は以下のように repeat() を使って記述しても同じことです。

.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: 100px repeat(2, 50px);
}

以下は1行目を100px、2行目を利用可能な高さの3分の1、3行目を利用可能な高さの3分の2に設定する例です。

.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: 100px 1fr 2fr;
}

minmax() 関数

CSS 関数の minmax() を使用するとトラックの最小値と最大値を設定できます。

以下が minmax() のおおまかな書式です。

minmax(最小値, 最大値)

どちらの引数も px や em などを使った長さやパーセント、fr、またはキーワード(max-content, min-content, auto)のいずれかを取ります。

説明
Length px や rem、 em などを使った長さ
Percentage %(パーセント)の単位
Flexible Length fr 単位。グリッドコンテナ内の利用可能なスペースを分割する割合。但し、現時点では minmax() の最小値には使用できません(最大値としてのみ使用可能)。
max-content グリッドトラックを占めるグリッドアイテムの max-content contribution の最大値
min-content グリッドトラックを占めるグリッドアイテムの min-content contribution の最大値
auto 最大値として使用する場合は max-content と同じです。最小値として使用する場合は最大の最小サイズになります。

参考:coliss/minmax()を使うとMedia Queries無しでレスポンシブが簡単に実装できる

minmax() 関数は以下のプロパティの中で使用することができます。

minmax() 関数を使うと、グリッドの行や列のサイズを定義する際に、最小サイズを設定してコンテンツに合わせて広げられるようにすることができます。

以下は grid-auto-rows で minmax() を使って、行のトラックの最小サイズを 50px に指定して最大サイズに auto を指定することでコンテンツに合わせて行の高さを拡大させる例です。

.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: minmax(100px, auto);
}

以下は grid-template-rows を使って1行目は 80px で固定、2行目は最小100pxでコンテンツにあわせて高さを拡大、3行目は 50px で固定にする例です。

.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: 80px minmax(100px, auto) 50px;
}

パーセントの単位も指定できます。

以下は grid-template-columns を使って1列目は最小幅200px、最大幅50%で残りを2つの列に等しく(1/2 ずつ)配分する例です。

.container {
  display: grid;
  grid-template-columns: minmax(200px, 50%) 1fr 1fr;
}

fr 単位を指定することもできます。但し、現時点では fr 単位は第2パラメータの最大値としてしか使用できません。

以下は grid-template-columns を使って1列目は最小幅300px、最大幅 1fr、残りの2列はそれぞれ 1fr を指定しています。

.container {
  display: grid;
  grid-template-columns: minmax(300px, 1fr) 1fr 1fr;
}

以下はコンテナーの幅が700pxの場合の例です。1列目は最小幅の300pxになり、残りの400pxを残りの2つの列に 1fr と 1fr として 200px ずつ割り当てられます。

コンテナー全体の幅が 900px より広い場合(2列目と3列目の幅が300pxを超える値を取れるだけ広い場合)は1列目も 1fr となり、全ての列が 1fr になります。

repeat() を使った便利なパターン

スクリーンサイズに合わせてカラム数を変更させるグリッド

以下はスクリーンサイズに合わせてコンテナに収まる限り多くの同じ幅の列のグリッドを作成する例です。

この例では列の幅の最小値は200px、行の高さの最小値は100pxにしています。

grid-template-columnsrepeat() 関数を使って、第1パラメータに auto-fill(コンテナーをオーバーフローさせない最大の数)を指定します。

キーワード auto-fill(または auto-fit)を指定することで、ブラウザはスクリーンサイズに合わせてカラムの数を算出(決定)します。

第2パラメータには minmax() を使用して最小値は必要な最小トラックサイズ(この例では200px)を、最大値は 1fr を指定します。

行の高さは grid-auto-rows で minmax() を使用して最小値に100pxを、最大値は auto を指定します。

.container {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  grid-auto-rows: minmax(100px, auto);
}

スクリーンサイズに合わせて最小幅200pxの等幅の列が作成されます。

<div class="container">
  <div class="item1">item1</div>
  <div class="item2">item2</div>
  <div class="item3">item3</div>
  <div class="item4">item4</div>
  <div class="item5">item5</div>
</div>

auto-fill/auto-fit

repeat() 関数の第1パラメータに auto-fill の代わりに auto-fit を指定しても特定のコンテナーサイズまでは同様に動作します。

auto-fill

auto-fill の場合、余ったスペースに最小幅を持った空のトラックを可能な限り追加して埋める(fill する)動作をします。

この例の場合、最小幅は200pxなので、コンテナーの幅が1200pxになると6つ目の空の列を挿入し、幅が1400pxになると7つ目の空の列を挿入します。

grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));

auto-fit

auto-fit の場合、余ったスペースの空の繰り返しトラックが折りたたまれ、空のトラックの幅が0pxとみなされるため、全体を 1fr の幅の列で埋めつくされます(fit します)。

grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));

サンプル(auto-fill/auto-fit)

参考:Auto-Sizing Columns in CSS Grid

グリッドギャップ gap

グリッドトラック間の余白(ガター)をグリッドギャップと呼びます(または単にギャップと呼びます)。

設定するには以下のプロパティを使用します。

ギャップを設定するプロパティ
プロパティ 旧プロパティ(※) 説明
gap grid-gap 行間のギャップ(row-gap)及び列間のギャップ(column-gap)の両方を同時に設定
row-gap grid-row-gap 行間のギャップを設定
column-gap grid-column-gap 列間のギャップを設定

※ ギャップ関連のプロパティは以前は grid- という接頭辞を付けていましたが接頭辞なしに仕様変更されています。但し、一部のブラウザが接頭辞なしのプロパティに対応していないため、それらに対応するには両方のプロパティを指定することができます(grid- 接頭辞付きのプロパティを先に記述)。

ブラウザの対応状況:caniuse

ギャップの値は、px や rem などの長さの単位またはパーセントで指定できますが、fr 単位は使えません。

また、ギャップの内側に何かを配置することはできません。

以下は行間及び列間のギャップの両方に 20px を指定する例です。

.container {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr;
  gap: 20px;  /* 行間と列間に 20px */
}

接頭辞なしのプロパティに対応していないブラウザ用に以下のように両方を記述することができます。

.container {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr;
  grid-gap: 20px; /* grid- 接頭辞付きのプロパティ(古い記述方法) */
  gap: 20px;
}

以下は行間のギャップを 20px、列間のギャップを 10px に指定する例です。

.container {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr;
  gap: 20px 10px; /* 行間:20px  列間:10px */
}

以下と同じことです。

.container {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr;
  row-gap: 20px;  /* 行間:20px  */
  column-gap: 10px;  /* 列間:10px */
}

グリッドアイテムの配置

デフォルトでは(位置や範囲を指定しなければ)グリッドは各アイテムをセルに順番に配置しますが、明示的に位置や範囲を指定することができます。

グリッドアイテムを特定の位置に配置するにはグリッドラインで指定するラインベースとエリアに名前をつけて指定するエリアベースの2つの方法があります。

ラインベースの配置

ラインベースの配置はグリッドラインの番号を指定することでアイテムをグリッド上に配置します。

ライン(グリッドライン)はグリッドを分割する垂直および水平の線のことで、グリッドの上下左右の端にも存在し番号が振られています。

英語や日本語(横書き)の左から右に記述する言語では、列(column)の1ライン目がグリッドの左側にあり、行(row)の1ライン目が上端にあり順番に正の番号が振られます。

列や行の数を指定した明示的なグリッドの場合は逆方向に-1から順に負の番号も振られます(以下の図ではカッコ内の番号)。

以下は3行3列のグリッドですが、行の水平方向のラインは4本、列の垂直方向のラインは4本あります。

ラインベースの配置では grid-column や grid-row プロパティを使って開始と終了のラインの番号を指定することでアイテムを配置します。

終点の列または行のラインをターゲットとして値 -1 を使用し、負の値を使用して終点から内側に向かって指定することもできますが、これは明示的グリッドに対してのみ有効です(明示的なグリッドとは自ら定義したグリッドのことで、自動的にブラウザが生成したグリッドは暗黙的なグリッドと呼ばれます)。

grid-column / grid-row

開始ラインと終了ラインの指定には以下のプロパティを使用することができます。

プロパティ 説明
grid-column-start 列においてのグリッドアイテムの開始位置を指定します。
grid-column-end 列においてのグリッドアイテムの終了位置を指定します。
grid-row-start 行においてのグリッドアイテムの開始位置を指定します。
grid-row-end 行においてのグリッドアイテムの終了位置を指定します。
grid-column grid-column-start および grid-column-end の一括指定(ショートハンド)プロパティ。開始と終了の列ライン番号を / (スラッシュ)で区切って指定します。
grid-row grid-row-start および grid-row-end の一括指定(ショートハンド)プロパティ。開始と終了の行ライン番号を / (スラッシュ)で区切って指定します。
grid-area エリアベースの配置でエリアの名前を指定する際にも使いますが、4角のライン番号を / (スラッシュ)で区切って指定することができます(grid-row および grid-column を一括指定することができます)。

以下は grid-template-columnsgrid-template-rows で定義した3列3行のトラックで構成されるグリッドに3つのアイテムを配置する例です。

<div class="container">
  <div class="item1">item1</div>
  <div class="item2">item2</div>
  <div class="item3">item3</div>
</div>
.container {
  display: grid;
  grid-template-columns: repeat(3, 200px);
  grid-template-rows: repeat(3, 100px);
}

.item1 {
  grid-column-start: 1; /* 列での開始位置(ライン番号)を指定 */
  grid-column-end: 4;   /* 列での終了位置(ライン番号)を指定 */
  grid-row-start: 1;    /* 行での開始位置(ライン番号)を指定 */
  grid-row-end: 2;      /* 行での終了位置(ライン番号)を指定 */
}

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

.item3 {
  grid-column-start: 2;
  grid-column-end: 4;
  grid-row-start: 2;
  grid-row-end: 4;
}

最初のアイテム(.item1)は列の1から列の4(右端のグリッドライン)まで、行の1から行の2で終わるエリアに配置されます。

.item1 {
  grid-column-start: 1;
  grid-column-end: 4;
  grid-row-start: 1;
  grid-row-end: 2; /* トラックの幅が1の場合は終了のライン指定を省略可能 */
}

トラックの幅が1の場合は終了のラインの指定を省略可能

トラックの幅が1(隣り合わせのトラック)の場合、それはデフォルトなので終了のラインを省略することができます。上記の場合、行のトラックの幅が1なので grid-row-end:2 は省略することができます。

span キーワード

span キーワードを使ってアイテムがまたがる行・列の数を指定することもできます。.item1 は span を使って以下のように記述することができます。

.item1 {
  grid-column-start: span 3;
  grid-row-start: 1; /* 幅が1なので終了は省略 */
}

2番目のアイテム(.item2)は列の1から列の2まで、行の2から行の4で終わるエリアに配置されます。列のトラックの幅が1なので grid-column-end:2 は省略することができます。

.item2 {
  grid-column-start: 1;
  grid-column-end: 2;  /* トラックの幅が1の場合は終了のライン指定を省略可能 */
  grid-row-start: 2;
  grid-row-end: 4;
}

3番目のアイテム(.item3)は列の2から列の4まで、行の2から行の4で終わるエリアに配置されます。

.item3 {
  grid-column-start: 2;
  grid-column-end: 4;
  grid-row-start: 2;
  grid-row-end: 4;
}

span を使って以下のように記述することもできます。

.item3 {
  grid-column-start: span 2;
  grid-row-start: span 2;
}

grid-column と grid-row で一括指定

grid-column と grid-row を使うと簡潔に記述することができます。一括指定する場合は、開始と終了のライン番号をスラッシュで区切って指定します(開始番号 / 終了番号)。

上記のアイテムの配置は以下のように記述することができます。

幅が1の場合は既定値(デフォルト)なので、終了番号を省略することが可能です。

.item1 {
  grid-column: 1 / 4;
  grid-row: 1 / 2;  /* grid-row: 1 でも同じ */
}

.item2 {
  grid-column: 1 / 2;  /* grid-column: 1 でも同じ */
  grid-row: 2 / 4;
}

.item3 {
  grid-column: 2 / 4;
  grid-row: 2 / 4;
}

grid-area で一括指定

grid-area を使うと配置するアイテムの行と列の開始および終了番号を以下の順番で一括指定することができます。

行開始番号 / 列開始番号 / 行終了番号 / 列終了番号

grid-area: grid-row-start / grid-column-start / grid-row-end / grid-column-end

これまでの例は以下のように記述することもできます。

.item1 {
  grid-area: 1 / 1 / 2 / 4;

  /* 以下と同じ
  grid-row-start: 1;
  grid-column-start: 1;
  grid-row-end: 2;
  grid-column-end: 4;
  */

  /* 以下でも同じ
  grid-row: 1 / 2;
  grid-column: 1 / 4;
   */
}

.item2 {
  grid-area: 2 / 1 / 4 / 2;

  /* 以下と同じ
  grid-row-start: 2;
  grid-column-start: 1;
  grid-row-end: 4;
  grid-column-end: 2;
   */

  /* 以下でも同じ
  grid-row: 2 / 4;
  grid-column: 1 / 2;
  */
}

.item3 {
  grid-area: 2 / 2 / 4 /4;

  /* 以下と同じ
  grid-row-start: 2;
  grid-column-start: 2;
  grid-row-end: 4;
  grid-column-end: 4;
  */

  /* 以下でも同じ
  grid-row: 2 / 4;
  grid-column: 2 / 4;
  */
}

グリッドレイアウトの例

以下は2列3行で構成されるグリッドレイアウトの例です。

grid-template-columns: 1fr 300px; で2列目は固定幅の 300px にして、残りのスペースを 1fr で1列目に割り当てています。この場合、1列目の 1fr は auto にしても同じことになります。

また、ヘッダーとフッターの高さは grid-template-rows でそれぞれ 100px と 120px に設定して、メインとサイドの高さは minmax(200px, auto) を指定して最小200pxでコンテンツに合わせるようにしています。

HTML
<body>
  <div class="container">
    <div class="header">header</div>
    <div class="main">main</div>
    <div class="aside">aside</div>
    <div class="footer">footer</div>
  </div>
</body>
CSS(ボーダーや背景色は省略しています)
.container {
  display: grid;
  grid-template-columns: 1fr 300px;
  grid-template-rows: 100px minmax(200px, auto) 120px;
  gap: 1rem;
}

.header {
  grid-column: 1 / 3;
  grid-row: 1 / 2;
}

.main {
  grid-column: 1 / 2;
  grid-row: 2 / 3;
}

.aside {
  grid-column: 2 / 3;
  grid-row: 2 / 3;
}

.footer {
  grid-column: 1 / 3;
  grid-row: 3 / 4;
}

以下は body 要素に display: grid を指定して、その直接の子要素の header や main、aside、footer 要素をアイテムとしてレイアウトする例です(表示は上記の例と同じになります)。

HTML
<body>
  <header>header</header>
  <main>main</main>
  <aside>aside</aside>
  <footer>footer</footer>
</body>
CSS
body {
  display: grid;
  grid-template-columns: 1fr 300px;
  grid-template-rows: 100px minmax(200px, auto) 120px;
  gap: 20px;
}

header {
  grid-column: 1 / 3;
  grid-row: 1 / 2;
}

main {
  grid-column: 1 / 2;
  grid-row: 2 / 3;
}

aside {
  grid-column: 2 / 3;
  grid-row: 2 / 3;
}

footer {
  grid-column: 1 / 3;
  grid-row: 3 / 4;
}
レスポンシブデザインに対応

レスポンシブデザインに対応させるのは簡単です。

メディアクエリを使って特定のブレークポイントでシングルカラムからマルチカラムになるようにします。

以下は前述の例を 40em 以上ではマルチカラムにする例です。ブロック要素は垂直方向に重なるので、単に 40em 以上で display:grid を指定しています。

@media (min-width: 40em) {
  body {
    display: grid;
    grid-template-columns: 1fr 300px;
    grid-template-rows: 100px minmax(200px, auto) 120px;
    gap: 20px;
  }

  header {
    grid-column: 1 / 3;
    grid-row: 1 / 2;
    background-color: #D1F9D2;
  }

  main {
    grid-column: 1 / 2;
    grid-row: 2 / 3;
    background-color:#F8DEDF;
  }

  aside {
    grid-column: 2 / 3;
    grid-row: 2 / 3;
    background-color:#DCE7F9;
  }

  footer {
    grid-column: 1 / 3;
    grid-row: 3 / 4;
    background-color:#FBF4D1;
  }
}

または、以下のように 40em 未満では grid-template-columns: 1fr を指定して1カラムにして、40em 以上の幅ではマルチカラムにすることもできます。この場合、シングルカラムでもギャップを指定できるので便利です。

body {
  display: grid;
  grid-template-columns: 1fr; /* モバイルではシングルカラム */
  gap: 10px;
}

@media (min-width: 40em) {
  body {
    grid-template-columns: 1fr 300px;
    grid-template-rows: 100px minmax(200px, auto) 120px;
    gap: 20px;
  }

  header {
    grid-column: 1 / 3;
    grid-row: 1 / 2;
    background-color: #D1F9D2;
  }

  main {
    grid-column: 1 / 2;
    grid-row: 2 / 3;
    background-color:#F8DEDF;
  }

  aside {
    grid-column: 2 / 3;
    grid-row: 2 / 3;
    background-color:#DCE7F9;
  }

  footer {
    grid-column: 1 / 3;
    grid-row: 3 / 4;
    background-color:#FBF4D1;
  }
}

サンプル

グリッドフレームワーク

グリッドフレームワークを使わなくても、簡単に12列や16列のグリッドを使ってレイアウトすることができます。

以下は前述とほぼ同じレイアウトを12列のグリッドに配置する例です。

repeat() を使って幅が 1fr の12列のグリッドを定義し、各アイテムをラインベースで割り当てています。

ヘッダーとフッターには全幅(ライン1〜13)を、メイン(main)には 8fr、サイドには 4fr を割り当てています。

前述の例ではサイド(aside)を 300px の固定にしましたが、この例では 4fr 分を指定しています。

HTML
<body>
  <header>header</header>
  <main>main</main>
  <aside>aside</aside>
  <footer>footer</footer>
</body>
CSS (背景色やボーダーの設定は省略)
body {
  display: grid;
  grid-template-columns: 1fr;  /* モバイルではシングルカラム */
  gap: 10px;
}

/* 画面幅が 40em 以上ではマルチカラム */
@media (min-width: 40em) {
  body {
    display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    /* または、単に grid-template-columns: repeat(12, 1fr); */
    grid-template-rows: 100px minmax(200px, auto) 120px;
    gap: 20px;
  }
  header {
    grid-column: 1 / 13;
    grid-row: 1; /* grid-row: 1 / 2 の省略形 */
  }
  main {
    grid-column: 1 / 9;
    grid-row: 2;  /* grid-row: 2 / 3 の省略形 */
  }
  aside {
    grid-column: 9 / 13;
    grid-row: 2;  /* grid-row: 2 / 3 の省略形 */
  }
  footer {
    grid-column: 1 / 13;
    grid-row: 3;  /* grid-row: 3 / 4 の省略形 */
  }
}

サンプル

エリアベースの配置

エリアは一つ以上のセルからなるアイテムを配置する長方形の領域のことです。

エリアベースの配置では以下のプロパティを使って、名前付きのエリアを定義してアイテムを配置することができます。

プロパティ 説明
grid-template-areas セルに名前を付けてエリアを定義(コンテナー)
grid-area 各アイテムを配置するエリアの名前を指定(アイテム)
grid-template grid-template-rows、grid-template-columns、grid-template-areas を一括指定するショートハンドプロパティ

以下はエリアベースで配置する2列3行で構成されるグリッドレイアウトの例です。

この例ではコンテナーに対して grid-template-columns と grid-template-rows で2列3行のグリッドを定義し、grid-template-areas でエリアを定義しています。

そして各エリアに grid-area で定義したエリアの名前を指定しています。

HTML
<body>
  <div class="container">
    <header class="header">header</header>
    <main class="content">content</main>
    <div class="sidebar">side bar</div>
    <footer class="footer">footer</footer>
  </div>
</body>
CSS
.container {
  display: grid;
  /* 列を定義 */
  grid-template-columns: 1fr 240px ;
  /* 行を定義 */
  grid-template-rows: 100px minmax(200px, auto) 120px;
  /* エリアを定義 */
  grid-template-areas:
    "header  header"
    "content sidebar"
    "footer  footer";
  /* ギャップを定義 */
  gap: 20px;
}

/* 各エリアに名前を指定 */

.header {
  grid-area: header;
}
.content {
  grid-area: content;
}
.sidebar {
  grid-area: sidebar;
}
.footer {
  grid-area: footer;
}

サンプル

grid-template-areas

grid-template-areas を使ってグリッドセル(グリッドラインに囲まれた領域)に任意の名前を付けてエリアを定義することができます。

ダブルクォーテーションで囲んだ文字列が行を表します。各文字列は構造がわかりすいように改行することができます(文字列内で改行することはできません)。

行の文字列の中に半角スペースで区切ってセルに対してエリアの名前を記述します。構造がわかりやすいように任意の数の半角スペースを挿入できます。

複数のセルにまたがるようにするには、名前を繰り返します。

grid-template-areas:
  "header  header"  /* 1行目 */
  "content sidebar" /* 2行目 */
  "footer  footer"; /* 3行目 */
/* 1列目   2列目 */ 

また、以下のような決まりがあります。

  • グリッドのすべてのセルを埋め尽くす必要があります。
  • セルを空のままにする(名前を付ける必要がない)場合は . (ピリオド)を使用します。見た目を整えるためピリオドを複数続けて記述することができます。
  • エリアは長方形である必要があります(L字型のエリアを定義することはできません)。

前述の例では、grid-template-columns と grid-template-rows を使ってトラックのサイズを指定してグリッドを定義しましたが、grid-template-areas だけでグリッドを定義することができます(エリアのサイズは auto になります)。

以下は7つの名前付きのエリア(と3つの空のエリア)を定義する例です。

HTML
<div class="container">
  <div class="green">green</div>
  <div class="blue">blue</div>
  <div class="yellow">yellow</div>
  <div class="pink">pink</div>
  <div class="orange">orange</div>
  <div class="purple">purple</div>
  <div class="gray">gray</div>
</div>
CSS
.container {
  display: grid;
  grid-template-areas:
    "green  green   orange  orange"  /* 1行目 */
    "pink   blue    orange  orange"  /* 2行目 */
    "pink   gray    ....    purple"  /* 3行目 */
    "....   yellow  yellow  ....";   /* 4行目 */
 /*  1列目   2列目   3列目    4列目  */
}

/* 各エリアに名前を指定 */
.green {
  grid-area: green;
  background-color: #A6E2AC;
}
.blue {
  grid-area: blue;
  background-color: #C7DBF7;
}
.yellow {
  grid-area: yellow;
  background-color: #F6F5C8;
}
.pink {
  grid-area: pink;
  background-color: #FBD2D2;
}
.orange {
  grid-area: orange;
  background-color: #F8C98A;
}
.purple {
  grid-area: purple;
  background-color: #D6AFF7;
}
.gray {
  grid-area: gray;
  background-color:#EEEEEE;
}

行の中や行をまたがって同じ名前のセルが複数あると、対応するグリッドセルにまたがる単一の名前付きグリッド領域を生成します。但し、これらのセルが長方形にならないと、宣言は無効になります。

Firefox のインスペクターでグリッドラインを表示すると以下のようになっています。

grid-template

grid-template を使うと grid-template-areasgrid-template-rowsgrid-template-columns を一括指定することができます。

grid-template の指定方法(構文)は複数あります。

以下は grid-template-areas の各行の指定(ダブルクォーテーションの文字列)の後にその行の高さを指定し、行の指定の最後にスラッシュで区切り、各列の幅を指定する例です(この指定方法の場合は repeat() は使えません)。

HTML
<div class="container">
  <div class="green">green</div>
  <div class="blue">blue</div>
  <div class="yellow">yellow</div>
  <div class="pink">pink</div>
  <div class="orange">orange</div>
  <div class="purple">purple</div>
  <div class="gray">gray</div>
</div>
.container {
  display: grid;
  grid-template:
    "green  green   orange  orange" 50px  /* "行の文字列" 行の高さ */
    "pink   blue    orange  orange" 50px
    "pink   gray    ....    purple" 50px
    "....   yellow  yellow  ...."   50px / /* スラッシュの後に列の幅を指定 */
    100px  100px   100px   100px ;
 /* 列の幅  列の幅   列の幅   列の幅 */
}

.green {
  grid-area: green;
  background-color: #A6E2AC;
}
.blue {
  grid-area: blue;
  background-color: #C7DBF7;
}
.yellow {
  grid-area: yellow;
  background-color: #F6F5C8;
}
.pink {
  grid-area: pink;
  background-color: #FBD2D2;
}
.orange {
  grid-area: orange;
  background-color: #F8C98A;
}
.purple {
  grid-area: purple;
  background-color: #D6AFF7;
}
.gray {
  grid-area: gray;
  background-color:#EEEEEE;
}

行と列を区切るスラッシュの前後には改行を入れることができます(以下は改行を入れない例)。

.container {
  display: grid;
  grid-template:
    "green  green   orange  orange" 50px
    "pink   blue    orange  orange" 50px
    "pink   gray    ....    purple" 50px
    "....   yellow  yellow  ...."   50px / 100px 100px 100px 100px ;
}

上記は以下と同じことです。

.container {
  display: grid;
  grid-template-areas:
    "green  green   orange  orange"
    "pink   blue    orange  orange"
    "pink   gray    ....    purple"
    "....   yellow  yellow  ....";
  grid-template-rows:  repeat(4, 50px);
  grid-template-columns: repeat(4, 100px);
}
grid-template-rows と grid-template-columns を一括指定

エリアベースの指定ではありませんが、grid-template を使うと grid-template-rows と grid-template-columns を一括指定することもできます。

grid-template: grid-template-rows の値 / grid-template-columns の値 

HTML
<div class="container">
  <div class="item1">item1</div>
  <div class="item2">item2</div>
  <div class="item3">item3</div>
  <div class="item4">item4</div>
  <div class="item5">item5</div>
  <div class="item6">item6</div>
  <div class="item7">item7</div>
</div>

以下を記述すると3行3列のグリッドが定義されます。

CSS
.container {
  display: grid;
  grid-template: 50px 100px 50px / 150px 1fr 250px;
}

上記は以下のショートハンド指定で同じことです。

.container {
  display: grid;
  grid-template-rows: 50px 100px 50px;
  grid-template-columns: 150px 1fr 250px;
}

聖杯(Holy Grail)レイアウト

grid-template を使うと以下のような「聖杯レイアウト」を簡潔に記述することができます。

HTML
<div class="container">
  <header class="header">header</header>
  <div class="left-side">left sidebar</div>
  <main class="main">main content</main>
  <div class="right-side">right sidebar</div>
  <footer class="footer">footer</footer>
</div>
CSS
.container {
  display: grid;
  grid-template: auto 1fr auto / minmax(150px, auto) 1fr minmax(150px, auto);
}

.header {
  grid-column: 1 / 4;
}

.left-side {
  grid-column: 1 / 2;
}

.main {
  grid-column: 2 / 3;
}

.right-side {
  grid-column: 3 / 4;
}

.footer {
  grid-column: 1 / 4;
}

サンプル

グリッドのネスト(入れ子)

グリッドアイテムをグリッドコンテナーにすることで、グリッドを入れ子にすることができます。

グリッドアイテムに display: grid; を指定すればグリッドコンテナーになり、グリッドアイテム自身がグリッドコンテナになります。

以下のような HTML がある場合、body 要素に display: grid を指定してグリッドコンテナーにすると、その直接の子要素の header、main、aside、footer 要素がグリッドアイテムになります。

そして main 要素にも display: grid を指定すると、main 要素はグリッドアイテムであり同時にグリッドコンテナーになります。

<body>
  <header>
    <h1>header</h1>
  </header>
  <main>
    <div class="content">
      <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
    </div>
    <div class="content">
      <p>Qui at adipisci illum, molestiae enim nostrum ratione!</p>
    </div>
    <div class="content">
      <p>Assumenda obcaecati, optio.</p>
    </div>
  </main>
  <aside>
    <h3>aside</h3>
    <p>Quae delectus, at corporis obcaecati, quas ea magni consectetur.</p>
  </aside>
  <footer>
    <h4>footer</h4>
  </footer>
</body>
body {
  display: grid;   /* グリッドコンテナー */
  grid-template-columns: 1fr minmax(120px, 300px);
  grid-template-rows: 100px auto 120px;
  gap: 20px;
}
header {
  grid-column: 1 / 3;
  grid-row: 1 / 2;
}
main { /* グリッドアイテムでありグリッドコンテナーでもある */
  grid-column: 1 / 2;
  grid-row: 2 / 3;
  display: grid;   /* グリッドコンテナー */
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 10px;
}
aside {
  grid-column: 2 / 3;
  grid-row: 2 / 3;
}
footer {
  grid-column: 1 / 3;
  grid-row: 3 / 4;
}

main の中に h2 要素を配置すると、h2 要素も main の直接の子要素なのでグリッドアイテムになります。この例の場合、repeat() に auto-fit を指定しているので、画面幅やコンテンツによりレイアウトが変わってきます。

<main>
  <h2 class="heading">main</h2>
  <div class="content">
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
  </div>
  <div class="content">
    <p>Qui at adipisci illum, molestiae enim nostrum ratione!</p>
  </div>
  <div class="content">
    <p>Assumenda obcaecati, optio.</p>
  </div>
</main>

サンプル

h2 要素をグリッドアイテムにしないようにするには、.content を囲む要素(以下の例では .contents)を追加して、その要素に display:grid を指定するとシンプルです。

<body>
<header>
  <h1>header</h1>
</header>
<main>
  <h2>main</h2>
  <div class="contents"> <!-- 追加 -->
    <div class="content">
      <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
    </div>
    <div class="content">
      <p>Qui at adipisci illum, molestiae enim nostrum ratione!</p>
    </div>
    <div class="content">
      <p>Assumenda obcaecati, optio.</p>
    </div>
  </div>
</main>
<aside>
  <h3>aside</h3>
  <p>Quae delectus, at corporis obcaecati, quas ea magni.</p>
</aside>
<footer>
  <h4>footer</h4>
</footer>
</body>
body {
  display: grid;
  grid-template-columns: 1fr minmax(120px, 300px);
  grid-template-rows: 160px auto 120px;
  gap: 20px;
}
header {
  grid-column: 1 / 3;
  grid-row: 1 / 2;
}
main {
  grid-column: 1 / 2;
  grid-row: 2 / 3;
}
aside {
  grid-column: 2 / 3;
  grid-row: 2 / 3;
}
footer {
  grid-column: 1 / 3;
  grid-row: 3 / 4;
}
main .contents {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 10px;
}

サンプル

グリッドのレイヤー(重なり)

グリッドアイテムは同じセルに重ねて配置することができます。重なり順は z-index を使って指定することができます。

以下は3つのアイテムを重ねて表示する例です。重なり順は最後に配置されているものが前面になりますが、以下では z-index で重なり順を変更しています。

HTML
<div class="container">
  <div class="blue"></div>
  <div class="yellow"></div>
  <div class="green"></div>
</div>
CSS
.container {
  display: grid;
  grid-template-columns: repeat(3, 100px);
  grid-template-rows: repeat(3, 100px);
}
.blue {
  grid-column: 1/3;
  grid-row: 1/3;
  z-index: 3;
  background-color:rgba(49,120,245,0.5);
}
.yellow {
  grid-column: 2/4;
  grid-row: 2/4;
  z-index: 2;
  background-color:rgba(239,249,115,0.8);
}
.green {
  grid-column: 1/4;
  grid-row: 1/4;
  z-index: 1;
  background-color:rgba(162,244,183,0.5);
}

この例では背景色を rgba で指定して半透明にしています。

アイテムに角丸 50% を適用すると以下のような表示になります。

.container > div {
  border-radius: 50%;
}

自動配置アルゴリズム

デフォルトではグリッドアイテムは CSS Grid Layout Module で規定されている自動配置アルゴリズム(Grid Item Placement Algorithm)に従って自動的に配置されます。

デフォルトでは明示的に定義した列と行にアイテムが収まらない場合は自動的に行が追加されます。

自動配置の既定のフロー(grid-auto-flow : row)では行ごとにアイテムを配置します。

グリッドは、それぞれのアイテムを1行目のそれぞれのセルに配置します。 grid-template-rows プロパティを使用して追加の行を作成した場合は、グリッドはこれらの行にアイテムを配置し続けます。明示的なグリッドにすべてのアイテムを配置するのに十分な行がない場合は、新たに暗黙の行が作成されます。

自動配置の既定のルールより

配置の順番(order)

デフォルトの自動配置では、HTML での出現順に左上から配置されていきますが、order プロパティを使うと順番を変更することができます。

HTML
<div class="container">
  <div class="one">1</div>
  <div class="two">2</div>
  <div class="three">3</div>
  <div class="four">4</div>
  <div class="five">5</div>
  <div class="six">6</div>
  <div class="seven">7</div>
  <div class="eight">8</div>
  <div class="nine">9</div>
</div>
CSS (背景色やボーダーの設定は省略)
.container {
  display: grid;
  grid-template-columns:  100px 100px 100px;
  grid-auto-rows: 100px;
  gap: 10px;
}

上記の場合、HTML での出現順に左上から配置されます。

全てのアイテムに order で順番を指定すると配置順を変更することができます。

但し、例えば .one のみに order: 3 を指定すると、.one のアイテムは3番めには配置されず、一番最後に配置されます。

.one {
  order: 3;
}
.two {
  order: 9;
}
.three {
  order: 7;
}
.four {
  order: 2;
}
.five {
  order: 4;
}
.six {
  order: 5;
}
.seven {
  order: 1;
}
.eight {
  order: 6;
}
.nine {
  order: 6
}

自動的な配置と明示的な配置

自動的な配置と grid-row や grid-column などで明示的に位置を指定した配置を一緒に使用すると、明示的に配置したアイテムが先ず指定された位置に配置され、その後空いたスペースに自動的に配置されるアイテムが左上から配置されていきます。

以下は3つのアイテムのみ明示的に位置を指定して配置する例です。

.one {
  grid-row: 1 / 2;
  grid-column: 2 / 3;
}
.two {
  grid-row: 2 / 3;
  grid-column: 1 / 2;
}
.three {
  grid-row: 3 / 4;
  grid-column: 3 / 4;
}

1(.one), 2(.two), 3(.three) を明示的に位置を指定して配置した場合の例。

dense パッキングアルゴリズム

配置アルゴリズムは特に何も指定しない(デフォルト)場合、スパース(sparse)アルゴリズムが適用されます。

sparse アルゴリズムは空いているスペースがあっても自動配置されたアイテムを順番に配置します("sparse" packing algorithm)。

これに対して dense アルゴリズムは順番に関係なく空いているスペースをできるだけ埋めるようにアイテムを配置します("dense" packing algorithm)。

dense アルゴリズムに切り替えるには grid-auto-flow プロパティにキーワード dense を指定します。

grid-auto-flow プロパティには1つのキーワードを指定するか、row または column に dense を加えて2つのキーワードを指定することができます。

以下のいずれかを指定できます。

grid-auto-flow: row; /* デフォルト  */
grid-auto-flow: column;
grid-auto-flow: dense;
grid-auto-flow: row dense;
grid-auto-flow: column dense;

以下のような構成の HTML で、

HTML
<div class="container">
  <div class="one">1</div>
  <div class="two">2</div>
  <div class="three">3</div>
  <div class="four">4</div>
  <div class="five">5</div>
  <div class="six">6</div>
  <div class="seven">7</div>
  <div class="eight">8</div>
  <div class="nine">9</div>
</div>

grid-template-columns と grid-auto-rows を使ってグリッドを定義し、いくつかのアイテムは明示的に位置を指定し、残りは自動的に配置してみます。

CSS
.container {
  display: grid;
  grid-template-columns: 100px 100px 100px;
  grid-auto-rows: 100px;
  gap: 10px;
}

.one {
  grid-column: 1 / 2;
  grid-row: 1 / 3;
}
.two {
  grid-column: 3 / 4;
  grid-row: 1 / 2;
}
.three {
  grid-row:span 2;
  grid-column: span 2;
}
.four {
  grid-column: 2 / span 2;
}
.five {
  grid-row:span 2;
  grid-column: span 2;
}

上記の場合、以下のようにスペースが空いてしまい空のエリアができてしまいます。

このような場合に、grid-auto-flow プロパティにキーワード dense を指定すると、空いているスペースをできる限り埋めてアイテムを配置することができます。

.container {
  display: grid;
  grid-template-columns: 100px 100px 100px;
  grid-auto-rows: 100px;
  gap: 10px;
  grid-auto-flow: dense;  /* dense アルゴリズムを指定 */
}

grid-auto-flow: dense を指定すると、前述のグリッドのアイテムは以下のように配置されます。

参考: