前提
grid-template-columns: repeat(3, 1fr); のように 列数を数字で決めて repeat だけ使う分には慣れていた。一方で minmax() や auto-fit / auto-fill はほとんど手を付けず、必要になったときに真似書きで済ませることが多かった。
minmax や auto-fit / auto-fill について、基本的な使い方と共通点・差を整理して、今後は活用できるようにしたい。
検証用デモページで実際の挙動を確認しながら整理した。
grid-template-columns
minmax
minmax(最小, 最大) は、列トラックの幅を下限と上限のあいだに収めたいときに使う。grid-template-columns の列定義の一部として repeat() と組み合わせるのが一般的である。
基本的な使い方
最小値と最大値を指定する。
例: grid-template-columns: repeat(3, minmax(100px, 300px));
活用例:改行させずに幅を守り、横スクロールへ回す
「中身のテキストを 無理に折り返したくない」「列として ある程度の最小幅は保ちたい」といったとき、各列に minmax(◯px, …) の 最小側を効かせると、狭い画面ではトラックの合計幅がコンテナを超えやすくなる。コンテナに overflow-x: auto を付ければ、横スクロールで閲覧させるレイアウトにできる。
検証デモ では repeat(3, minmax(340px, 350px)) と overflow-x: auto の組み合わせが載っている(数値は例として読み替えてよい)。画面幅を狭めると、スクロールバーが出てくる。
auto-fit / auto-fill との組み合わせ
repeat(auto-fit, minmax(◯px, 1fr)) のように minmax の第 2 引数に 1fr を置くと、余った幅の配分のされ方が、後述の auto-fit と auto-fill のどちらかで大きく変わる。minmax 側で「最小幅はここまで」という 下限を決めておくイメージで読むと、auto-* の節とつながりやすい。
auto-fit と auto-fill
repeat(5, 1fr) のように 列数を固定できない(またはブレークポイントのたびに数字を書き換えたくない)とき、コンテナ幅と「1 列の最小幅」から列数を自動で決めるのが repeat の第一引数にある auto-fill と auto-fit である。
実際の見た目の対比は、デモの auto-fit・auto-fill を並べて触ると理解が進みやすい。
共通の振る舞い(ざっくり)
どちらも、コンテナに 載せられるだけの列トラックを(minmax の最小値などを手がかりに)用意しようとする方向は同じである。細部は仕様書の定義に委ねるが、日々の実装では 「空いた列をどう扱うか」 の差が結果に出る。
差が出る振る舞い(空トラックと 1fr)
ざっくり言うと、次のような整理になる(minmax(◯px, 1fr) を想定)。
- auto-fill: 親コンテナに まだ余白があるとき、中身のない列(空のグリッドトラック)も作られる側に振る舞う。
1frで余白を配分するとき、その 空の列にも幅の伸びが割り当てられる。その結果、アイテムが載っている列だけが親いっぱいに広がるわけではなく、トラック 1 本分あたりの伸びにとどまることが多い。 - auto-fit: 同様に余白があっても、アイテムがない繰り返し列は折りたたまれる(空トラックは幅 0 に近い扱いになる)。
1frの余白は 実質アイテムのある列に回りやすく、親要素の幅いっぱいまで広がることがある。アイテムが 1 つだけのときなど、1 カードが横に大きく見える状況になりうる。
開発者ツールのグリッドオーバーレイで見ると、空トラックが残るかどうかの差が分かりやすい。下図は アイテムが 1 つだけのときの対比である(上段 auto-fit、下段 auto-fill)。

件数が少ないレイアウトでは どちらを選ぶかでカード幅の印象が変わるため、デザインの意図に合わせて切り替える判断になる。
固定の列数が必要な場面
repeat(3, 1fr) のように 列数を数字で書く場合、画面が狭くなって列を減らしたいときは ブレイクポイントごとに repeat(2, 1fr) へ切り替える、といった 明示的な指定が必要になる。反面、どの幅で何列かがコード上はっきりする。
一方、auto-fit や auto-fill を使うと コンテナ幅に応じて列数が勝手に決まるため、幅の断ち切りごとに列数だけ書き換える手間はかからない。可変グリッドとしてはとても便利である。
ただし 列数が fluid に変わること自体が、レイアウトの意図を壊すことがある。次のようなときは repeat(N, 1fr) で列数をはっきり決めた方がデザインと折り合いが付きやすい。
例: 動的サイトの一覧で 投稿を最大 9 件だけ並べる。3 列なら 3×3 でちょうど埋まり、行のバランスが取れる。ところが auto-fit / auto-fill 任せで幅によって 2 列になってしまうと、最終行に 1 件だけ残り、余白や視線の止まり方が意図とズレやすい。この場合は 列数をメディアクエリで明示する(狭い画面では 2 列にするが、9 件前提なら 3 列に固定し続ける幅帯を広く取る/件数や可視件数を調整する、など)方が筋がよい。
要するに 「常にきれいな行列になる件数・列の関係」がデザインの条件になっているときは、自動列数に頼りすぎない。
グリッドアイテムの直下の子に min-width: 0 を付けると、長いテキストなどが原因で 列幅だけ意図せず膨らむのを防ぎやすい。検証デモの .p-grid でも同様の指定が入っている。
参考
- auto-fill / auto-fit(説明とデモ・仕様の意訳が丁寧): ASCII.jp:これは便利!CSS Gridのauto-fillとauto-fitの使い分けでRWDが捗る(2018 年稿。転載である旨は元ページに記載あり)
- 手元の検証デモ(本番): グリッドレイアウト