セルをドラッグして描く CSS Grid ジェネレーター
この CSS Grid ジェネレーターのステージにあるボックスは、本物の display: grid コンテナです。上と左のルーラーには、列・行のトラックごとに指定した値とブラウザーが計算した px、そして線番号が表示されます。空きセルをドラッグするとその範囲を占めるエリアができ、エリアをドラッグするとセル単位で移動し、選択中のエリアの右下の角をドラッグすると拡大・縮小できます。ルーラーのチップをクリックすれば、そのトラックのサイズを 1fr・200px・minmax(120px, 1fr) のように変更できます。
ステージの下には、今の 1fr が何 px なのかが計算の順序どおりに文章で表示されます。幅に合わせて列を自動で作る場合は、列がいくつ入るかも式で示されます。完成したレイアウトは、grid-template-areas を使ったエリア名方式、または線番号方式の CSS としてコピーでき、HTML もまとめて持ち出せます。「リンクをコピー」を押すと、現在のレイアウトが URL に含まれます。
Grid が向いているレイアウト: 行と列を一緒に揃えたいとき
CSS Grid は、先に列と行の境界を決めてから、その区画に要素を置く 2 次元のレイアウトです。区画のサイズは要素の内容ではなくトラックが決めるため、複数の行にまたがっても上下のセルの境界がぴったり揃います。次のような画面で特に威力を発揮します。
- ページ全体の骨組み: ヘッダー・サイドバー・本文・フッターのように、位置が決まった領域を分けるときに使います。エリア名で書いておけば、CSS を読むだけでレイアウトが見えてきます(サンプル「基本ページ」「聖杯レイアウト」)。
- ダッシュボード: 小さな指標のセルと、2 マス以上を占める大きなグラフを同じグリッドに並べるときに使います(サンプル「ダッシュボード」)。
- カード一覧: 画面幅によって列数が変わっても、すべての行でカードの幅が同じになります。Flexbox で折り返すと最後の行のカードが広がりがちですが、Grid のカードはトラックの幅に従うので、そうはなりません(サンプル「自動調整カード」)。
- サイズの異なる写真のまとまり: 2 マス、4 マスを占める写真を混ぜ、
denseで隙間を埋めます(サンプル「写真モザイク」)。 - 重ね置き: 2 つのエリアに同じセルを割り当てると、画像の上に文字を載せるレイアウトを位置計算なしで作れます。ステージでエリアを別のエリアの上にドラッグすると、重なった状態を確認できます。
メニューやボタンのまとまりのように、一方向に並べてその行の中だけで空間を分けるレイアウトなら、Flexbox のほうがシンプルです。
使い方
- サンプルを選びます。最上部の 9 つのタイルのどれかをクリックすると、トラック・間隔・エリアがまとめて切り替わります。変わるエリアは、元の位置から新しい位置へ滑るように動きます。
- トラックを決めます。上の行の列・行ボタンでトラックを増減し、ルーラーのチップをクリックしてサイズを変更します。右側の操作パネルでは値を直接入力したり、よく使う値を選んだりでき、選択したトラックの前後にトラックを挿入することもできます。
- エリアを描きます。空きセルをドラッグするとエリアができ、エリアをドラッグすると移動し、右下の角をドラッグするとサイズが変わります。キーボードでは、エリアにフォーカスして矢印キーで 1 マスずつ移動し、Shift と矢印キーで拡大・縮小し、Delete キーで削除します。エリア名は操作パネルで変更します。
- 幅を確かめます。上の行の「全体」・768・480・360 ボタンやステージ右下のハンドルでコンテナの幅を変えると、fr トラックがどう縮むか、自動列がいくつに変わるかがすぐにわかります。
- コピーします。エリア名と線番号のどちらで書くかを選び、「CSS をコピー」または「HTML + CSS をコピー」を押します。「プレビューの装飾を含める」をオンにすると枠線と背景色も入るので、空のファイルに貼り付けてもセルが見えます。
トラック値の読み方
grid-template-columns と grid-template-rows には、トラックごとにサイズを 1 つずつ書きます。同じ値が続く場合は repeat(3, 1fr) のように省略でき、このツールもすべてのトラックが同じときはその形で出力します。
| 値 | サイズの決まり方 | こんなときに使います |
|---|---|---|
200px | コンテナの幅に関係なく固定 | サイドバー、アイコン用のセル |
25% | コンテナの内側の幅に対する割合。間隔は別に加算 | 比率を正確に守りたいとき(合計 100% で間隔があるとはみ出す) |
1fr | 他のトラックと間隔を除いた残りの空間の割り当て | 余った空間をすべて埋めたいとき |
auto | 内容のサイズ。fr トラックがなければ余った空間まで広がる | 高さを内容に合わせたいヘッダー・フッターの行 |
min-content | 内容が最も狭くなれる幅(最も長い単語) | ラベルのように、できるだけ狭くしたいセル |
max-content | 内容を折り返さず 1 行に並べた幅 | 折り返したくない短い項目 |
minmax(120px, 1fr) | 最小 120px から最大 1fr まで | 狭くなりすぎては困るセル |
minmax(0, 1fr) | 最小 0 から最大 1fr まで | 長い単語があっても列幅を均等に分けたいとき |
fit-content(240px) | 内容のサイズに従うが、240px を超えない | 内容が短ければ狭く、長ければ上限まで |
1fr は何 px か: 残りの空間を分ける順序
fr は固定の長さではなく、残りの空間を分けるための倍率です。ブラウザーは次の順序で 1fr のサイズを決めます。
- 内側の幅から、間隔(トラック数 − 1 個分)と fr 以外のトラックのサイズを引きます。これが残りの空間です。
- 残りの空間を fr の倍率の合計で割ると、1fr のサイズが求まります。倍率の合計が 1 未満のときは 1 で割るため、残りの空間の一部が空いたままになります。
- fr トラックのうち、最小サイズが自分の割り当て分より大きいものは、その最小サイズで固定し、残りの fr トラックだけでもう一度分けます。
1frの最小サイズは auto なので、セル内の長い単語や画像の幅が最小サイズになります。
下の表は、内側の幅 800px、列の間隔 16px のコンテナ(最後の行だけ内側 600px、間隔 0)で Chromium 151 が計算した列幅です。ステージに同じ値を入力すると、下の文章に同じ式が表示されます。
| grid-template-columns | 残りの空間 | 1fr | 列幅 |
|---|---|---|---|
1fr 1fr 1fr | 768px | 256px | 256 · 256 · 256 |
200px 1fr | 584px | 584px | 200 · 584 |
1fr 2fr 1fr | 768px | 192px | 192 · 384 · 192 |
240px 1fr 2fr | 528px | 176px | 240 · 176 · 352 |
25% 1fr | 584px | 584px | 200 · 584 |
0.5fr 0.25fr | 784px | 784px(倍率の合計 0.75 → 1 で割る) | 392 · 196(196px は空きになる) |
minmax(240px, 1fr) 1fr 1fr | 600px → 360px | 180px | 240 · 180 · 180 |
最後の行では、最初に 600 ÷ 3 = 200px で分けますが、1 列目の最小サイズ 240px が割り当て分の 200px より大きいため、1 列目を 240px に固定します。残りの 360px を 2 つの列が 180px ずつ分けます。2fr の列が 1fr の列のちょうど 2 倍になるのも、どちらの列も割り当て分が最小サイズより大きいときだけです。
エリア名と線番号
列が n 個あるグリッドには、縦の線が 1 番から n + 1 番まであります。ステージのルーラーの上に付いている小さな数字がこの線番号です。grid-column: 1 / 3 は 1 番線から 3 番線まで、つまり列 2 つ分を占めるという意味で、grid-row: 2 / 4 は行 2 つ分を占めます。最後の線は -1 とも書けるので、1 / -1 は列数に関係なく全幅になります。
grid-template-areas は、行ごとに引用符で囲んだ文字列を書き、セルごとにエリア名を並べます。空のセルにはピリオド(.)を書きます。サンプル「基本ページ」をエリア名方式で書くと次のとおりです。
.grid {
display: grid;
grid-template-columns: 180px 1fr;
grid-template-rows: 56px 1fr 48px;
grid-template-areas:
"header header"
"side main"
"footer footer";
gap: 12px;
}
.header { grid-area: header; }
.side { grid-area: side; }
同じ名前を書いたセルは、1 つの長方形になっていなければなりません。L 字に曲がっていたり離れていたりすると宣言全体が無効になります。すると grid-area: 名前 を指定した要素はそのエリアを見つけられず、明示的なグリッドの外にできた同じセルにすべて重なって置かれます。文字列ごとのセル数も揃える必要があります。2 つのエリアが同じセルを重ねて使うレイアウトは名前では書けないため、このツールは重なったエリアができると線番号方式に切り替えて書き出し、その理由をコードの上に表示します。
エリア名方式には、CSS だけを見てレイアウトを思い描けることと、メディアクエリで文字列だけを差し替えて画面幅ごとのレイアウトを組み直せることという利点があります。線番号方式は、12 列グリッドのようにセルが多い場合や、エリアを重ねたい場合に、より短く書けます。
auto-fit と auto-fill: 幅に合わせて列数を決める
「幅に合わせて自動」を選ぶと、列の定義は repeat(auto-fill, minmax(min(100%, 160px), 1fr)) の形になります。ブラウザーははみ出さない範囲でできるだけ多くの列を作り、その数は ⌊(内側の幅 + 間隔) ÷ (最小幅 + 間隔)⌋ です。min(100%, 160px) は、親が 160px より狭いときに最小幅を親の幅まで下げて、列が横にはみ出さないようにします。
auto-fit と auto-fill の違いが見えるのは、エリアの数が列数より少ないときだけです。auto-fill は空の列をそのまま残し、auto-fit は空の列のサイズを 0 に折りたたみ、その両側の間隔も一緒にたたむので、残ったエリアが広がります。最小幅 160px、間隔 16px でエリアが 3 つの場合の結果は次のとおりです。
| 内側の幅 | 列数 | auto-fill のセル幅 | auto-fit のセル幅 |
|---|---|---|---|
| 360px | 2 | 172px | 172px |
| 600px | 3 | 189.3px | 189.3px |
| 800px | 4 | 188px | 256px |
| 1000px | 5 | 187.2px | 322.7px |
360px では列が 2 つなので 3 つ目のエリアは次の行に下がり、600px ではエリア数と列数が同じなので両方式の結果が一致します。カードが 1、2 枚のときに広がりすぎるのを避けたいなら auto-fill、ある分のカードで幅いっぱいを埋めたいなら auto-fit を選びます。
明示したグリッドの外: 暗黙の行と dense
grid-template-rows で決めた行よりエリアが多いと、ブラウザーは行を追加で作ります。こうしてできた行を暗黙の行と呼び、そのサイズは grid-auto-rows が決めます(初期値は auto)。ステージでは、暗黙のトラックのチップとセルを点線で描きます。カード一覧では、行をまったく指定せず grid-auto-rows だけを指定することがよくあります。
位置を指定していないエリアは、HTML の順序どおりに入れるセルを探します。2 マスのエリアが行末に入りきらないと、次の行へ移って前に空きセルを残します。grid-auto-flow: dense を指定すると、後ろにある小さなエリアが前の空きセルを埋めます。サンプル「写真モザイク」で「隙間を埋める」をオフにすると 1 行 4 列が空き、オンにすると p5 がその位置に上がってきます。ただし dense が変えるのは画面上の見た目の順序だけで、Tab キーの移動順とスクリーンリーダーの読み上げ順は HTML の順序のままです。
セル内での揃え
エリアは、初期値の stretch でセルを埋め尽くします。justify-items はセル内での横位置を、align-items は縦位置を決め、start・center・end にするとエリアは内容のサイズに縮んでその位置に置かれます。両方を center にするのは place-items: center の 1 行と同じで、サンプル「中央揃え」がこのレイアウトです。特定のエリアだけを個別に揃えるには、そのエリアに justify-self・align-self を指定します。
トラックのサイズの合計がコンテナより小さいとき、トラック全体は開始側(左上)に寄ります。ステージの下の文章が「右側が空いています」と知らせるのがこの場合で、全体を中央に移したいときはコンテナに justify-content: center を加えます。
ブラウザー対応
以下は MDN のブラウザー互換性データに記載された、最初に対応したバージョンです。このツールが出力するコードは subgrid を使いません。
| 機能 | Chrome | Firefox | Safari |
|---|---|---|---|
display: grid, grid-template-columns | 57 | 52 | 10.1 |
grid-template-areas | 57 | 52 | 10.1 |
gap(グリッド) | 66 | 61 | 12 |
min() 関数 | 79 | 75 | 11.1 |
| subgrid(参考) | 117 | 71 | 16 |
よくある間違い
- 1fr の列の幅がそれぞれ違う。セルに長い URL や大きな画像があり、最小サイズが割り当て分より大きくなっている場合です。
minmax(0, 1fr)に変え、あふれる文字は別途折り返します。 - 25% を 4 つ並べるとはみ出す。% のトラックには間隔が含まれません。間隔が 16px なら 48px はみ出すので、
repeat(4, 1fr)を使います。 - 1fr の行が伸びない。コンテナの高さが auto だと、分けるべき残りの高さがありません。
heightやmin-height: 100dvhのように高さを指定します。 - grid-template-areas がまるごと無視される。文字列ごとのセル数が違う、または同じ名前が長方形になっていない場合です。
- 狭い画面でカードが横にはみ出す。
minmax(240px, 1fr)は、親が 240px より狭くても 240px を保ちます。minmax(min(100%, 240px), 1fr)に変えます。 - 列が 1 つ増えて横スクロールが出る。span が列数より大きいと暗黙の列ができます。自動列で狭い幅のときに特に起こりやすいので、360px ボタンで確認します。
- dense で埋めたら読む順序がずれる。画面上の順序だけが変わっています。順序が重要なリストなら dense をオフにするか、HTML の順序を直します。
制限と注意
- ステージが表示するのは、左から右へ横書きする方向だけです。
- ステージのエリアには名前の文字だけが入っており、文字でトラックが広がらないよう
min-width: 0とoverflow: hiddenを指定してあります。配置プロパティだけのデフォルトのコードにはこの 2 行がないため、同じ名前の文字でも、最小サイズが auto の 1fr 列は文字の幅まで広がることがあります。「プレビューの装飾を含める」をオンにすると、この 2 行とステージの内側の余白・枠線・文字サイズが一緒に入り、ステージと同じサイズで描かれます。実際の内容が大きいと、auto・min-content・fr トラックのサイズはステージと変わります。 - 明示できるトラックは列・行それぞれ 12 個、エリアは 24 個までです。名前付きの線、負の線番号、subgrid、
grid-auto-columns、justify-content・align-content、エリアごとのjustify-self・align-self、メディアクエリはコードに含まれません。 - 高さ欄の値は、内側の余白を除いた内容の高さです。コードの
heightも同じ意味(content-box)で書き出します。 - 768・480・360 ボタンが変えるのはコンテナの幅です。画面(ビューポート)の幅を基準にするメディアクエリとは異なります。
- fr の解説文は、ブラウザーが描画したトラックのサイズから計算をやり直しています。0.6px を超えてずれたときは、その式が概算であることを知らせます。
- リンクのコピーでは、エリア名まで URL に含まれます。
基準日 W3C CSS Grid Layout Module Level 2(Candidate Recommendation Draft 2025-03-26)と MDN のブラウザー互換性データは、2026-10-21 に原文で確認しました。表の列幅は、Chromium 151 で実際の grid コンテナを使って測った値です。
出典
- 01W3C: CSS Grid Layout Module Level 2Candidate Recommendation Draft 2025-03-26。§6.6 グリッドアイテムの自動最小サイズ、§7.2.1 トラックのサイズ(minmax() の外の fr は最小 auto)、§7.2.3.2 auto-fill・auto-fit の繰り返し数と空トラックの折りたたみ、§7.3 grid-template-areas(長方形でないと宣言は無効)、§7.5 暗黙のグリッドと grid-auto-rows、§7.7 grid-auto-flow の dense、§11.1 間隔(折りたたまれたトラックの間隔)、§12.7.1 fr サイズの求め方(倍率の合計が 1 未満の場合、最小サイズが大きいトラックを除外して再計算)
- 02MDN: grid-template-columnsトラック値の構文、ブラウザー互換性表: Chrome 57・Firefox 52・Safari 10.1、subgrid は Chrome 117・Firefox 71・Safari 16
- 03MDN: grid-template-areasエリア名の構文、ブラウザー互換性表: Chrome 57・Firefox 52・Safari 10.1
- 04MDN: gapブラウザー互換性表: グリッドレイアウトでは Chrome 66・Firefox 61・Safari 12
- 05MDN: min()ブラウザー互換性表: Chrome 79・Firefox 75・Safari 11.1
よくある質問
CSS Grid で同じ幅の 3 列を作るにはどうしますか?
コンテナに display: grid と grid-template-columns: repeat(3, 1fr) を指定します。内側の幅 800px、列の間隔 16px なら、間隔 32px を引いた 768px を 3 等分して各列が 256px になります。セル内に長い URL や画像があっても幅を揃えたいときは、repeat(3, minmax(0, 1fr)) と書きます。
fr と % は何が違いますか?
% はコンテナの内側の幅に対する割合なので間隔が別に加わりますが、fr は間隔と他のトラックを先に引いた残りの空間を分けます。間隔 16px で 25% を 4 つ使うと 48px はみ出しますが、1fr を 4 つ使ってもはみ出しません。
auto-fit と auto-fill は何が違いますか?
どちらもはみ出さない範囲でできるだけ多くの列を作りますが、エリアの数が列数より少ないとき、auto-fill は空の列を残し、auto-fit は空の列を 0 に折りたたんで残りのエリアを広げます。内側 800px、最小 160px、間隔 16px でエリアが 3 つなら、auto-fill は 188px、auto-fit は 256px です。
grid-template-areas を書いたのに効きません。
文字列ごとのセル数が同じか、同じ名前を書いたセルが 1 つの長方形になっているかを確認します。どちらか一方でも守られていないと、宣言全体が無効になります。各要素には grid-area: 名前 を別に指定する必要があり、名前に引用符は付けません。
画面幅に応じて列数を変えるにはどうしますか?
grid-template-columns: repeat(auto-fit, minmax(min(100%, 160px), 1fr)) と書くと、メディアクエリなしで幅に合わせて列数が変わります。列数は (内側の幅 + 間隔) ÷ (最小幅 + 間隔) を切り捨てた値です。このツールで「幅に合わせて自動」を選び、ハンドルで幅を変えると、列が切り替わる位置を確認できます。
Grid の中の要素を中央に置くにはどうしますか?
コンテナに place-items: center を指定するか、justify-items と align-items をどちらも center にします。縦方向の中央に置くにはセルに余った高さが必要なので、行またはコンテナの高さも決めておきます。サンプル「中央揃え」を押すとすぐに確認できます。
1fr にした行が伸びません。
コンテナの高さが auto だと、分ける残りの高さがないため、fr の行は内容の高さまでしか伸びません。height や min-height: 100dvh のようにコンテナの高さを決めると、1fr の行が残りの高さを受け持ちます。
Grid と Flexbox はどちらを使えばよいですか?
行と列の境界を一緒に揃えたいページの骨組み・ダッシュボード・カード一覧には Grid、一方向に並べてその行の中で空間を分けるメニューやボタンのまとまりには Flexbox が向いています。両者は併用することが多く、Grid で領域を分け、各領域の中のボタンの行は Flexbox で揃えます。