3 行でできるグリッド
コンテナに display: grid を指定し、grid-template-columns で列を並べます。子要素は順番に (英語なら左から右へ) セルを埋め、列がいっぱいになるたびに新しい行が始まります:
アイテムが 7 つ、列が 3 つなので、2 行が埋まり、3 行目は 1 列目にアイテム 7 が入ります。どの列も同じ幅で、行の中のアイテムはどれも同じ高さなので、端が縦にも横にもそろいます。これが grid が flexbox に加えるものです。
grid プレイグラウンド
grid-template-columns の値を入力するか、プリセットをクリックしてください。表示欄には、ブラウザが計算した列の幅 (getComputedStyle から) と、アイテムに必要だった行の数が表示されます:
注目してほしい点: 1fr 2fr では 2 列目がちょうど 1 列目の 2 倍になります。200px 1fr は 200px を保ち、残りを 2 列目に渡します。auto 1fr auto は両端の列を内容に合わせます。repeat(4, 100px) は伸び縮みする列がないので、終わりに空きが残ります。1fr 2 のような無効な値は無視され、グリッドは最後の有効な値を保ちます。
fr 単位
fr は「空きスペースの 1 単位分」という意味です。ブラウザはまず固定の列 (px、rem、%、auto の内容) とすき間を差し引き、残りを fr の列にその数値の比で分けます。
600px のコンテナ (すき間なし) の grid-template-columns | 列の幅 |
|---|---|
1fr 1fr 1fr | 200、200、200 |
1fr 2fr | 200、400 |
100px 1fr 1fr | 100、250、250 |
1fr 50% | 300、300 |
fr は % とは違います。パーセントとすき間を合わせると 100% を超えてはみ出すことがありますが、fr の列は常にすき間を引いた残りだけを分け合います。
repeat()、minmax()、メディアクエリなしのレスポンシブなグリッド
repeat(4, 1fr) は 1fr 1fr 1fr 1fr と同じです。minmax(120px, 1fr) は、120px より細くならず、伸びて分け前を取る列です。この 2 つを、数の代わりに auto-fill か auto-fit と組み合わせると、グリッドは収まるだけ列を作ります:
.cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
gap: 16px;
}
この 1 つの宣言で、コンテナに収まるだけの、180px 以上の列ができます。広い画面では何列も、スマートフォンでは 1 列になり、メディアクエリは要りません。auto-fill と auto-fit の違いは、アイテムが列より少ないときに現れます:
コンテナには 100px の列が 5 つ収まります。auto-fill は 5 列すべてを残すので、A、B、C はそれぞれ 112px で、空の列が 2 つ残ります。auto-fit は空の列をつぶすので、3 つのアイテムがそれぞれ約 187px まで伸びます。
アイテムの配置: grid-column と grid-row
グリッドのラインは始まりの端から 1 で番号が付きます。grid-column: 1 / 3 は「ライン 1 からライン 3 まで」、つまり 2 列分です。span 2 は「置かれた場所から 2 列分」、-1 は最後のラインです:
暗い色のアイテムは 1 行目全体を埋めます。青は 2 × 2 のブロックを、琥珀色は 2 行分を覆います。アイテム a と b は残りのセルを自動で埋めます。grid は置けるアイテムをすべて次の空いたセルに置くからです。grid-auto-rows: 60px は、grid-template-rows で宣言していない行の高さを決めます。
grid-template-areas: レイアウトの各部分に名前を付ける
ページのレイアウトでは、エリアに名前を付け、テキストで図を描きます。各文字列が 1 行、各単語が 1 セルで、アイテムは grid-area でエリアに入ります:
ヘッダーとフッターは、名前がその行の 2 つのセルを埋めているので、2 列にまたがります。真ん中の行は 1fr なので、280px のうち残りの高さをすべて使います。スマートフォンですべてを縦に積むには、メディアクエリでエリアを 1 列に描き直すだけです: grid-template-areas: "header" "side" "main" "footer" と grid-template-columns: 1fr。このパターンは メディアクエリのページ にあります。
セルの中で揃える
grid のアイテムは、初期状態でセルいっぱいに伸びます。次のプロパティでセルの中の位置を動かします:
| プロパティ | 書く場所 | 動かすもの |
|---|---|---|
justify-items | コンテナ | すべてのアイテムを行の方向 (インライン軸) に |
align-items | コンテナ | すべてのアイテムを上下 (ブロック軸) に |
place-items | コンテナ | ショートハンド: place-items: center で両方向の中央 |
justify-self / align-self | アイテム | 1 つのアイテム |
justify-content / align-content | コンテナ | グリッドがコンテナより小さいときの、トラック全体 |
display: grid; place-items: center; は、ボックスの中で 1 つの子要素を中央に置く一番短い方法です。
grid か flexbox か
grid は 2 次元です。列 (と行) を決めると内容がそれを埋めるので、ギャラリーのカードは最後の行でもすべて同じ幅になります。flexbox は 1 次元です。アイテムは 1 本の線に沿って内容に合わせてサイズが決まります。2 つは組み合わせやすく、ページとカードのギャラリーには grid、各カードの中のヘッダー行には flexbox が使えます。もう半分は flexbox のページ で解説しています。
順番とアクセシビリティ
grid-template-areas、grid-row、grid-column、order を使うとアイテムをどこにでも置けますが、スクリーンリーダーと Tab キーは HTML の順番に従います。ソースの順番 (ヘッダー、ナビゲーション、メイン、フッター) に意味を持たせ、grid はそれを並べるために使いましょう。意味の通らない HTML の順番を直すために使うのではありません。
よくある間違い
- アイテムに
display: gridを付ける。 親に付けます。grid のアイテムになるのは直接の子要素だけです。 - すき間とパーセントを一緒に使う。
grid-template-columns: 50% 50%とgap: 16pxでは 16px はみ出します。1fr 1frを使いましょう。 auto-fitのつもりでauto-fillを使う。 アイテムが少ないと、auto-fillは空の列を残します。アイテムを伸ばすならauto-fitに切り替えます。1frの列が分け前以上に広がる。1frの列は、一番長い内容 (長い URL、幅の広い画像) より小さくは縮みません。縮めるにはminmax(0, 1fr)を使います。- エリアの文字列が長方形になっていない。 名前付きのエリアはどれも長方形でなければならず、各行の文字列のセルの数もそろっている必要があります。そうでなければ
grid-template-areasの宣言全体が無視されます。 - ラインの番号が 1 から始まることを忘れる。 3 列にはラインが 4 本あります。3 列すべてにまたがるのは
1 / 4か1 / -1です。
よくある質問
CSS grid とは何ですか?
要素を行と列に同時に配置するレイアウトのしくみです。コンテナに display: grid を指定し、grid-template-columns で列を (必要なら行も) 定義すると、直接の子要素が順番にセルを埋めます。
CSS grid の 1fr はどういう意味ですか?
fr は grid コンテナの空きスペースの割合です。grid-template-columns: 1fr 1fr 1fr で均等な 3 列になり、1fr 2fr では 2 列目が 1 列目の 2 倍の幅になります。固定サイズとすき間が先に差し引かれ、fr の列が残りを分け合います。
auto-fill と auto-fit の違いは何ですか?
どちらも収まるだけ列を作ります。auto-fill は空の列を残すので、アイテムが少ないと細いままで、行の終わりに空きができます。auto-fit は空の列をつぶすので、アイテムが伸びて行を埋めます。行を埋めるだけのアイテムがあれば、2 つは同じに見えます。
grid のアイテムを 2 列にまたがらせるには?
アイテムに grid-column: span 2 を指定するか、始まりと終わりのラインを指定します: grid-column: 1 / 3 で 1 列目と 2 列目を覆います。-1 は最後のラインなので、grid-column: 1 / -1 で幅全体にまたがります。
flexbox ではなく grid を使うのはどんなときですか?
行と列をお互いにそろえる必要があるときに grid を使います。カードのギャラリー、ラベルをそろえたフォーム、ヘッダー、サイドバー、フッターのあるページなどです。ナビゲーションバーのように、アイテムが内容に合わせてサイズが決まる 1 行か 1 列には flexbox を使います。
grid-gap と gap は同じですか?
同じです。grid-gap、grid-row-gap、grid-column-gap は古い名前です。ブラウザは今も別名として受け付けますが、flexbox でも使える gap、row-gap、column-gap を書きましょう。