グリッドレイアウトの基本概念
CSS グリッドレイアウトは、二次元グリッドシステムを CSS にもたらします。グリッドは、主要なページ領域や小さなユーザーインターフェイス要素のレイアウトに利用できます。この記事では、 CSS グリッドレイアウトと、 CSS Grid Layout Level 1 仕様の一部の用語について紹介します。この記事では、その概要を紹介し、この一連のガイドの残りで詳細を説明します。
グリッドとは何か?
グリッドは、列と行を定義する水平線と垂直線の集合が交差したものです。要素をグリッド上の行と列の中に配置することができます。 CSS グリッドレイアウトには次のような特徴があります。
固定のトラックサイズと可変のトラックサイズ
例えばピクセル単位を使って、固定トラックサイズのグリッドを作成することができます。これであるグリッドに好きなレイアウトに合うようなピクセルを設定できます。また、可変サイズのグリッドを作成するために、パーセントやこの目的で制定された fr
単位を使用することができます。
アイテムの配置
グリッドの線番号や名前を使って、グリッドのある位置を指定してアイテムを配置することができます。グリッドには、位置が明示されていないアイテムの配置を制御するアルゴリズムも含まれています。
内容物を保持するための追加トラックの作成
グリッドレイアウトでは、明確にグリッドを定義することができます。グリッドレイアウトの仕様では、必要に応じて柔軟に行や列を追加できるようになっています。「コンテナーに収まるだけ多く数の列」を追加するような機能もあります。
配置の制御
グリッドには配置機能が含まれており、あるグリッド領域内でアイテムがどのように配置されるのか、グリッド全体がどのように配置されるかを制御できます。
重複する内容物の制御
グリッドコンテナー
グリッドコンテナーを作成するには、要素に対して display: grid
か display: inline-grid
を指定します。グリッドコンテナーを作成すると、直接の子要素がすべてグリッドアイテムへと変わります。
この例では、 wrapper クラスの div を親要素として、その内部には 5 個の子要素が含まれています。
<div class="wrapper">
<div>One</div>
<div>Two</div>
<div>Three</div>
<div>Four</div>
<div>Five</div>
</div>
.wrapper
をグリッドコンテナー化します。
.wrapper {
display: grid;
}
すべての直接の子要素がグリッド要素になりました。それらの要素をグリッドにする前とウェブブラウザー上での見た目に変化は無いでしょう。グリッドには単一列のグリッドが作成されただけだからです。この時点で、 Firefox の開発者ツールの一つであるグリッドインスペクター機能が便利であることを確認できます。上記の例を Firefox で表示してグリッドを調査すると、grid
値の隣に小さなアイコンが表示されているでしょう。これをクリックすると、その要素上のグリッドがブラウザーウィンドウ内にオーバーレイ表示されます。
CSS グリッドレイアウトについて学び、使っていく中で、このツールは、グリッドに何が起こっているかを視覚的に理解する助けになるでしょう。
この例をさらにグリッドらしくするためには、列トラックを追加する必要があります。
グリッドトラック
ここでは、grid-template-rows
および grid-template-columns
プロパティを使用してグリッド上に行と列を定義します。これらはグリッドトラックを定義します。グリッドトラックは、グリッド上の任意の 2 本の線の間にある空間です。下の画像で、グリッド内の最初の行トラックが強調表示されているのが確認できるでしょう。
グリッドトラックは grid-template-columns
プロパティと grid-template-rows
プロパティ、または省略形の grid
プロパティと grid-template
プロパティで定義します。トラックは、明示的グリッドで作成されたトラックの外側にグリッドアイテムを配置することで、暗黙的グリッドでも作成されます。
基本的な例
先述の例に対して grid-template-columns
プロパティを追加すると、列トラックのサイズが定義できます。
3 本の 200 ピクセル幅の列トラックを持つグリッドを作成しましょう。子要素はこのグリッドの各グリッドセルに 1 個ずつ配置されます。
<div class="wrapper">
<div>One</div>
<div>Two</div>
<div>Three</div>
<div>Four</div>
<div>Five</div>
</div>
.wrapper {
display: grid;
grid-template-columns: 200px 200px 200px;
}
単位 fr
トラックは、どの長さの単位でも定義できます。グリッドには、柔軟なグリッドトラックを作成できるようにするため、追加の長さの単位が導入されています。新しい単位 fr
は、グリッドコンテナー内の利用可能な空間の比を表します。次のグリッド定義は、利用可能なスペースに応じて伸縮する、幅が 3 等分されたトラックを作成します。
<div class="wrapper">
<div>One</div>
<div>Two</div>
<div>Three</div>
<div>Four</div>
<div>Five</div>
</div>
.wrapper {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
}
等しくない大きさ
この次の例では、1 つの 2fr
のトラックと 2 つの 1fr
のトラックの定義を作成します。利用可能な空間は、4 つに分割されます。そのうち 2 つが最初のトラックに与えられ、残りはそれぞれ次の 2 つのトラックに与えられます。
<div class="wrapper">
<div>One</div>
<div>Two</div>
<div>Three</div>
<div>Four</div>
<div>Five</div>
</div>
.wrapper {
display: grid;
grid-template-columns: 2fr 1fr 1fr;
}
変動する大きさと絶対的な大きさの混合
最後の例では、絶対サイズのトラックを fr
単位と混ぜて使用します。最初のトラックは 500px なので、この固定幅は利用可能な空間から除外されます。残りの領域は 3 つに分割され、比率に応じて 2 つの変動幅のトラックに割り当てられます。
<div class="wrapper">
<div>One</div>
<div>Two</div>
<div>Three</div>
<div>Four</div>
<div>Five</div>
</div>
.wrapper {
display: grid;
grid-template-columns: 500px 1fr 2fr;
}
repeat() 記法によるトラック列挙
多くのトラックを持つ大きなグリッドのため、repeat()
記法を使用して、トラック列挙のすべてまたは一部を繰り返すことができます。例えば、以下のグリッド定義を参照してください。
.wrapper {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
}
次のように書くこともできます。
.wrapper {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
反復記法は、トラック列挙の一部にも使えます。この次の例では、はじめに 20px のトラックを持ち、続けて 6 つの 1fr
のトラックのセクション、最後に 20px のトラックを持つグリッドを作成します。
.wrapper {
display: grid;
grid-template-columns: 20px repeat(6, 1fr) 20px;
}
反復記法はトラック列挙も取るので、トラック列挙の反復パターンの作成にも利用できます。この次の例で、グリッドは 10 本のトラックで構成されており、それは 1fr
のトラックに 2fr
のトラックが続くパターンを 5 回反復したものです。
.wrapper {
display: grid;
grid-template-columns: repeat(5, 1fr 2fr);
}
暗黙的および明示的なグリッド
上でグリッドの例を作成した時、列トラックを grid-template-columns
プロパティで具体的に定義しましたが、グリッドは勝手に行も作っていました。これらの行は暗黙的のグリッドの一部です。一方、明示的なグリッドは、grid-template-columns
または grid-template-rows
で定義された行と列から構成されます。
定義されたグリッドの外側に何かを配置した場合 (または内容物の量のために、より多くのグリッドトラックが必要な場合)、グリッドは暗黙的なグリッドに行と列を作成します。これらのトラックは、デフォルトで自動サイズ調整されるため、サイズはトラック内の内容物に基づいて決まります。
grid-auto-rows
と grid-auto-columns
プロパティで、暗黙的なグリッドに作成されたトラックのセットサイズを定義することもできます。
下の例では、grid-auto-rows
を使用して、暗黙的なグリッド内に作成されたトラックが 200px の高さになることを保証しています。
<div class="wrapper">
<div>One</div>
<div>Two</div>
<div>Three</div>
<div>Four</div>
<div>Five</div>
</div>
.wrapper {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: 200px;
}
トラックのサイズ指定と minmax()
明示的なグリッドのセットアップ時または自動生成された行や列のサイズを定義する時、最小サイズのトラックを与えておき、追加された内容物に合わせて広げられるようにしたいでしょう。例えば、行を 100 ピクセルより小さくしたくないが、内容物の高さが 300 ピクセルに引き伸ばされた場合は行の高さをそのサイズに引き伸ばしたい場合です。
グリッドでは、それを minmax()
関数で解決できます。この次の例では、grid-auto-rows
の値に minmax()
を使用しています。自動生成された行の高さの最小値は 100 ピクセル、最大値は auto
になります。値に auto
を使うと、この行のセルが内容物のサイズに応じて空間が引き伸ばされ、その高さに合わせられます。
.wrapper {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: minmax(100px, auto);
}
<div class="wrapper">
<div>One</div>
<div>
Two
<p>より多くのコンテンツがあります。</p>
<p>これによって、高さが 100 ピクセルよりも高くなります。</p>
</div>
<div>Three</div>
<div>Four</div>
<div>Five</div>
</div>
グリッド線
私たちがグリッドを定義する時、グリッドトラックを定義するのであり、グリッド線ではないことに注意しなければなりません。グリッドには、アイテムの配置時に使用する番号の付いた線が与えられます。3 列 2 行のグリッドには、4 本の縦線があります。
グリッド線の番号は、文書の書字方向に従って付けられます。左書き (left-to-right) の言語では、線 1 はグリッドの左手側にあり、右書き (right-to-left) の言語では、グリッドの右手側にあります。グリッド線には名前を付けることもできます。この方法については後のガイドで解説します。
グリッド線に対するアイテムの配置
グリッド線を基にした配置の詳細は、後の記事で解説します。次の例は、その簡単な方法のデモンストレーションです。アイテムを配置するとき、私たちはトラックではなくグリッド線を対象にします。
以下の例では、最初の 2 つのアイテムを、grid-column-start
, grid-column-end
, grid-row-start
および grid-row-end
の各プロパティを使用して 3 列トラックのグリッド上に配置します。左から右へ向かって、最初のアイテムは列の線 1 から列の線 4 に対して、右端のグリッド線まで配置されます。また、行の線 1 から始まり、行の線 3 で終わる 2 行のトラックに及びます。
2 番目のアイテムは、グリッド列の線 1 から始まり、1 トラックの幅になります。これはデフォルトであるため、終わりの線を指定する必要がありません。また、行の線 3 から 5 まで、2 行トラックに及びます。他のアイテムは、それぞれグリッド上の空スペースに配置されます。
<div class="wrapper">
<div class="box1">One</div>
<div class="box2">Two</div>
<div class="box3">Three</div>
<div class="box4">Four</div>
<div class="box5">Five</div>
</div>
.wrapper {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: 100px;
}
.box1 {
grid-column-start: 1;
grid-column-end: 4;
grid-row-start: 1;
grid-row-end: 3;
}
.box2 {
grid-column-start: 1;
grid-row-start: 3;
grid-row-end: 5;
}
メモ: Firefox の開発者ツールでグリッドインスペクターが使えることを忘れないでください。アイテムがグリッド線に対してどのように配置されるか知ることができます。
線による配置の一括指定
上記で使用した個別指定の値は、列の場合は grid-column
で 1 行に、行の場合は grid-row
で 1 行に圧縮できます。次の例では、先ほどのコードと同じ位置関係を、はるかに少ない CSS で実現しています。フォワードスラッシュ文字 (/
) の前の値が開始行、後の値が終了行となります。
領域が 1 つのトラックにしか及ばない場合は、終了値を省略することができます。
.wrapper {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: 100px;
}
.box1 {
grid-column: 1 / 4;
grid-row: 1 / 3;
}
.box2 {
grid-column: 1;
grid-row: 3 / 5;
}
グリッドセル
グリッドセル は、グリッド上の最も小さな単位です。コンセプトとしては、表のセルのようなものです。先述の例で、親要素のグリッドが定義されると、子アイテムが定義されたグリッドの各セルにレイアウトされる様を見てきました。下の画像では、グリッドの最初のセルをハイライトしています。
グリッド領域
アイテムは、行と列の複数のセルにまたがって配置でき、グリッド領域 を作ることができます。グリッド領域は四角形でなければなりません。例えば L 字型の領域は作れません。ハイライトされた領域は、2 行と 2 列にまたがるトラックです。
溝
グリッドセル間の 溝 (Gutters) または 路地 (alleys) は、 column-gap
および row-gap
プロパティを使用するか、一括指定の gap
で作成できます。下の例では、列間 10 ピクセル、行間 1em
の隙間を作っています。
.wrapper {
display: grid;
grid-template-columns: repeat(3, 1fr);
column-gap: 10px;
row-gap: 1em;
}
メモ:
グリッドが最初にブラウザーに実装されたとき、 column-gap
, row-gap
, gap
に grid-
の接頭辞がつき、それぞれ grid-column-gap
, grid-row-gap
, grid-gap
のようになっていました。
ブラウザーはすべて接頭辞なしの値に対応しましたが、接頭辞付きの版も安全に利用できるよう保守されるでしょう。
<div class="wrapper">
<div>One</div>
<div>Two</div>
<div>Three</div>
<div>Four</div>
<div>Five</div>
</div>
領域の前に占める溝による空間は、柔軟な長さの fr
トラックに割り当てられ、通常のグリッドトラックのようにサイズ設定のために用いられます。しかしながら、溝の内側に何かを配置することはできません。グリッド線を基準にした配置では、溝は太線のように扱われます。
入れ子状のグリッド
グリッドアイテムはグリッドコンテナーにもなります。次の例は以前作成したもので、2 個のアイテムが配置指定された 3 列のグリッドです。この例では、最初のアイテムにサブアイテムが含まれています。これらのアイテムはグリッドの直接の子ではないので、グリッドレイアウトに関係しない通常の文書フローで表示されています。
サブグリッドのない入れ子
この box1
に display: grid
を設定すると、トラック定義を与えてグリッドにすることができます。これらは新しいグリッド上にレイアウトされます。
.box1 {
grid-column-start: 1;
grid-column-end: 4;
grid-row-start: 1;
grid-row-end: 3;
display: grid;
grid-template-columns: repeat(3, 1fr);
}
* {
box-sizing: border-box;
}
.wrapper {
border: 2px solid #f76707;
border-radius: 5px;
gap: 3px;
background-color: #fff4e6;
display: grid;
grid-template-columns: repeat(3, 1fr);
}
.box {
border: 2px solid #ffa94d;
border-radius: 5px;
background-color: #ffd8a8;
padding: 1em;
color: #d9480f;
}
.box1 {
grid-column: 1 / 4;
}
.nested {
border: 2px solid #ffec99;
border-radius: 5px;
background-color: #fff9db;
padding: 1em;
}
この場合の入れ子状のグリッドは、親グリッドと関係しません。例で表示されているように、親グリッドの gap
を継承せず、入れ子状のグリッド内の線は親グリッドの線に沿いません。
サブグリッド
通常のグリッドに加えて、サブグリッドでは、親グリッドのトラック定義を使用するネストされたグリッドを作成することができます。
使用するには、入れ子上のグリッドの例を編集して、 grid-template-columns: repeat(3, 1fr)
のトラック定義を grid-template-columns: subgrid
へ変更しましょう。入れ子状のグリッドは親グリッドのトラックを利用してアイテムをレイアウトします。
.box1 {
grid-column-start: 1;
grid-column-end: 4;
grid-row-start: 1;
grid-row-end: 3;
display: grid;
grid-template-columns: subgrid;
}
z-index によるアイテムのレイヤー化
グリッドアイテムは、同じセルを占有することがあり、この場合は z-index
を使用してアイテムの重ね合わせの順序を制御することができます。
z-index のない重ね合わせ
先ほどの行番号順にアイテムを配置する例に戻ると、これを変更して 2 つのアイテムを重ねることができます。
<div class="wrapper">
<div class="box box1">One</div>
<div class="box box2">Two</div>
<div class="box box3">Three</div>
<div class="box box4">Four</div>
<div class="box box5">Five</div>
</div>
.wrapper {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: 100px;
}
.box1 {
grid-column-start: 1;
grid-column-end: 4;
grid-row-start: 1;
grid-row-end: 3;
}
.box2 {
grid-column-start: 1;
grid-row-start: 2;
grid-row-end: 4;
}
アイテム box2
が box1
に重なり、ソースコードに書かれた順に、後のものが先のものの上に表示されます。
順序の制御
アイテムを上に積む順序は、配置が指定されたアイテムと同様に、z-index
プロパティを使用して制御できます。box2
の z-index
を box1
より小さくすると、box1
の奥に表示されるようになります。
.wrapper {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: 100px;
}
.box1 {
grid-column-start: 1;
grid-column-end: 4;
grid-row-start: 1;
grid-row-end: 3;
z-index: 2;
}
.box2 {
grid-column-start: 1;
grid-row-start: 2;
grid-row-end: 4;
z-index: 1;
}
次のステップ
この記事では、グリッドレイアウト仕様の要点だけを見てきました。コード例を試してみてから、このガイドの次の部分に進みましょう。ここで本当に CSS グリッドレイアウトの詳細を掘り下げ始めます。