CSS Gridを使うならマスターしておきたいauto-fillとauto-fitの違い

Advertisement

CSS Gridって本当に便利だなぁと思う今日この頃ですが、そのなかでも特に注目しているのがrepeat()minmax()です。この2つのCSS関数を使うとグリッドレイアウトの構築が楽になるだけでなく、CSS Gridだけでメディアクエリなしでもレスポンシブなレイアウトが実現できます。

今回はそのrepeat()で使えるauto-fillauto-fitという値について。ちょっと違いが分かりづらいのでメモっておきたいと思います。

auto-fillとauto-fitの違い

auto-fillauto-fitの違いは実装例を見るのが一番わかりやすいので、まずはデモをご覧ください。repeat()auto-fillauto-fitminmax()を使ったデモです。

デモはこちら

デモページをブラウザで開いてウィンドウ幅を変えてみてください(CSS Gridがサポートされているブラウザはこちら )。なんとなく違いがわかったでしょうか?

下のGIFアニメのようになるはずです。

親要素の幅によって挙動が変わるCSS Gridのauto-fillとauto-fitの違いを表示したGIFアニメーション
  • auto-fillでは、親要素にスペースが余る場合、空のグリッドが作られます
  • auto-fitでは、親要素にスペースが余る場合、グリッド・アイテムの幅が変わってスペースが埋められます

ざっくり言ってしまうと、これら2つの違いはそんな感じなんですが、なぜこのようになっているのか、もう少し詳しく見て行きましょう。該当する部分のCSSとHTMLは以下のとおりです。

CSS

.grid-auto-fill,
.grid-auto-fit {
  display: grid;
  border: 1px solid #ddd;
  grid-auto-rows: 5em;
  grid-gap: 10px;
  padding: 10px;
  margin: 1em 0 2em;
  overflow: hidden;
}

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

.grid-auto-fit {
  grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
}

.grid-auto-fill > div,
.grid-auto-fit > div {
  padding: 10px;
  background: #ddd;
}

.grid-auto-fill.grid-auto-fitの違いは、repeat()auto-fillauto-fitの記述だけです。他はまったく同じです。

HTML

<h3>auto-fill</h3>
<div class="grid-auto-fill">
  <div>Item 1</div>
  <div>Item 2</div>
  <div>Item 3</div>
  <div>Item 4</div>
</div>
<h3>auto-fit</h3>
<div class="grid-auto-fit">
  <div>Item 1</div>
  <div>Item 2</div>
  <div>Item 3</div>
  <div>Item 4</div>
</div>

.grid-auto-fillauto-fill.grid-auto-fitauto-fitのグリッド・コンテナ(親要素)になります。グリッド・コンテナにはminmax()で指定した最小幅が100px、最大幅が1fr(フラクション)を指定した4つのグリッド・アイテムを入れています。

開発ツールでグリッドを表示させる

GIFアニメにあるようにグリッドをオーバーレイで表示させるには、FirefoxのCSS Gridインスペクターが便利ですよ。

さて、ここからはCSSの記述を詳しく見て行きます。まずはrepeat()について。

CSS Gridのrepeat()とは

CSS Gridでrepeat()関数を使うと、グリッドの繰り返しの指定ができます。たとえば、以下を指定すると

grid-template-columns: repeat(2, 100px 1fr);

以下の記述と同じになります。

grid-template-columns: 100px 1fr 100px 1fr;

便利ですね。

次にrepeat()で使えるauto-fillauto-fitについて説明します。これら2つはminmax()関数と一緒に使うと挙動に違いがでるので、組み合わせで使用する際の説明をします。

auto-fillの挙動

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

minmax()ではグリッドアイテムの最小幅と最大幅を指定しています。この記述だと最小幅が100px、最大幅が1fr(可変のフラクション)です。これら2つの値の間で幅を自動で調整してグリッドアイテムを表示してくれます。

ここでauto-fillを使うと、余ったスペースを新たな空のグリッドで埋めて(フィルして)くれます。なので、下のGIFアニメのように親要素の幅を広げてスペースが余るようにすると、ポコポコと新しいグリッドが生まれてくるんですね。

auto-fitの挙動

今度はauto-fitを入れてみます。

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

auto-fitを使うと、親要素で余ったスペースは崩されて幅が0pxとみなされます。そのため1frの幅を持つグリッドアイテムで余ったスペースが埋められるんですね。

念のため仕様を確認してみる

デモを見ればこれらの挙動は一目瞭然なんですが、念のため仕様ではどのように説明されているのか確認しておきます。

仕様ではauto-fillauto-fitについて以下のように書かれています。

auto-fillの仕様

When auto-fill is given as the repetition number, if the grid container has a definite size or max size in the relevant axis, then the number of repetitions is the largest possible positive integer that does not cause the grid to overflow its grid container (treating each track as its max track sizing function if that is definite or as its minimum track sizing function otherwise, and taking gap into account); if any number of repetitions would overflow, then 1 repetition. Otherwise, if the grid container has a definite min size in the relevant axis, the number of repetitions is the smallest possible positive integer that fulfills that minimum requirement. Otherwise, the specified track list repeats only once.

CSS Grid Layout Module Level 1: Repeat-to-fill: auto-fill and auto-fit repetitions

意訳してみます。

繰り返しの数値にauto-fillを指定すると、グリッド・コンテナの幅が当該の軸に向かって定数サイズか最大サイズの場合、繰り返し回数はグリッドがコンテナからはみ出ない最大の回数になる(それぞれのトラックを、それが定数の場合は最大サイズの機能として、それ以外の場合は最小サイズの機能として扱う。その際、ギャップも勘案する)。どの数値でもコンテナをはみ出てしまう場合は繰り返しは1回になる。また、グリッド・コンテナの幅が当該の軸に向かって定数の最小サイズの場合、繰り返しの回数は最低要件を満たす最小の整数になる。そうでなければ指定のトラック・リストは1回のみ繰り返す。

auto-fitの仕様

The auto-fit keyword behaves the same as auto-fill, except that after grid item placement any empty repeated tracks are collapsed. An empty track is one with no in-flow grid items placed into or spanning across it. (This can result in all tracks being collapsed, if they’re all empty.)

A collapsed track is treated as having a fixed track sizing function of 0px, and the gutters on either side of it—including any space allotted through distributed alignment—collapse.

CSS Grid Layout Module Level 1: Repeat-to-fill: auto-fill and auto-fit repetitions

こちらも、意訳してみます。

auto-fitもauto-fillと同じように振る舞います。ただし、グリッド・アイテムが置かれた後、繰り返された空のトラックは崩されます。空のトラックはインフローのグリッド・アイテムが置かれていない、または、スパンされていないトラックのことを指します。(すべてのトラックが空の場合、すべて崩されることもあります。)

崩されたトラックは0pxの固定のトラック・サイズの機能を持つものとして扱われ、アラインメントによって配分されたスペースを含む両サイドのガッターも崩れます。

うむ。なるほど。

文章だとイメージするのが難しいですが、そういうことなんですね(どういうこと?笑)。僕は何度も読み返して、ようやく理解できましたが「なるほど、だからそういう挙動になるのか」というのがわかりますね。

さいごにひとこと

先日の「CSS GridとFlexboxを使ってメディアクエリなしでレスポンシブにレイアウトする方法」でも書きましたが、CSS Gridのrepeat()minmax()を使いこなせるとグリッドレイアウトの可能性がすごく広がります。さらにjustify-contentalign-contentjustify-selfalign-selfあたりをマスターすれば最強ですね。

古いブラウザを気にせずにCSS Gridを自由に使える日が待ち遠しいです。

では、Happy gridding!(造語)

About the author

Rriverのステッカーが貼られたMacBookの向こうにいる自分のMemojiの似顔絵

「明日のウェブ制作に役立つアイディア」をテーマにこのブログを書いています。アメリカの大学を卒業後、ボストン近郊のウェブ制作会社に勤務。帰国後、東京のウェブ制作会社に勤務した後、ウェブ担当者として日英バイリンガルのサイト運営に携わる。詳しくはこちら

ウェブ制作・ディレクション、ビデオを含むコンテンツ制作のお手伝い、執筆・翻訳のご依頼など、お気軽にご相談ください。いずれも日本語と英語で対応可能です。まずは、Mastodon @rriver@vivaldi.net Twitter @rriver 、またはFacebook までご連絡ください。