サンプル
grid-template-columns: repeat(auto-fit, minmax(min(var(--minimum),100%), 1fr));
という宣言について分解して解説します。
.l-grid {
--minimum: 300px;
display: grid;
grid-template-columns: repeat(auto-fill,minmax(min(var(--minimum), 100%), 1fr));
gap: 1.875rem;
}
grid-template-columnsプロパティ
このプロパティは、列のグリッドトラックのサイズを指定できます。
列のグリッドトラックとは、以下の画像のように垂直方向の2つのグリッドライン間に挟まれた領域のことです↓
以下のようにスペース区切りで指定します↓
.hoge {
display:grid;
grid-template-columns:10px 100px 50px; //列数3
}
repeat()関数
repeat(repeat-count,track-size)
この関数は、grid-template-columns
やgrid-template-rows
で使用できます。
大量の列や行を作成するときに分かりやすくコンパクトに書くことができます。
第一引数に列や行の繰り返し数を指定し、第二引数に列や行のグリッドトラックのサイズを指定できます↓
.hoge {
display:grid;
grid-template-columns:repeat(3,1fr); //2列で幅均等のトラックサイズ
}
今回のサンプルのように列数にauto-fill
やauto-fit
の特別なキーワードを指定することもできます。
注意点
auto-*
を第一引数に指定した場合、以下のような指定はできません↓
.hoge {
display:grid;
grid-tempate-columns:repeat(auto-fit,1fr); // この指定はダメ
}
If you use
repeat() – CSS: Cascading Style Sheets | MDNauto-fill
orauto-fit
to set the repeat count, you may only specify track sizes using the<fixed-size>
type, not the<track-size>
type. This give us three main syntax forms forrepeat()
:
基本的にauto-*
を指定した場合、第二引数にはminmax()
関数を使用します。
auto-fillやauto-fitが指定された時の列数
このときの列数は、グリッドコンテナ幅を超えない可能な最大の正の整数になります。
グリッドコンテナ幅とは、display:grid;
が指定された要素の幅のことです。今回の場合、class名l-grid
のul
要素が該当します。
以下のコードの場合、4列で300pxのグリッドトラックが作成されます(gap
無しの場合)↓
.hoge {
display:grid;
width:1200px;//グリッドコンテナ幅が1200px
grid-template-columns:repeat(auto-fit,300px);//1200 / 300 = 4で4列
}
//列数は1でもグリッドコンテナの幅を超えない。(1200 / 1 = 1200)
//しかし、幅を超えない可能な最大の数だけ列を作成するので、4列になる。
//5列は無理(1200 / 5 = 240)
auto-fillとauto-fitの違い
二つの違いは、グリッドアイテムの数が作成されたグリッドトラックの数より少ない時に表れます。
グリッドアイテムとは、display:grid;
を指定した要素の直下の要素のことです。
少ない時に空のグリッドアイテムを作成するのがauto-fill
でauto-fit
は作成しません。
文字だと分かりづらいのでサンプルのグリッドアイテムの数を減らして挙動確認します。
auto-fillの場合
空のグリッドアイテムが作成されていることが分かります。また、グリッドトラック列のサイズが一定です。
auto-fitの場合
空のグリッドアイテムが作成されていません。また、各グリッドトラック列のサイズがグリッドコンテナを埋めるように広がっています。(minmax()
に1fr
を指定しているため。)
auto-fitとauto-fillどちらを使うべきか?
auto-fit
の場合、ブログでまだコンテンツが1つしかないときに、グリッドトラックサイズが極端に引き伸ばされて表示されてしまうかもしれません↓
auto-fill
の場合は、空のグリッドアイテムを作成するのでその心配はありません↓
基本的にauto-fill
を使用した方が良さそうです。
minmax()関数
minmax(min,max)
この関数は最小サイズから最大サイズの範囲を定義できます。
以下のプロパティの中で使用できます↓
grid-template-columns
grid-template-rows
grid-auto-columns
grid-auto-rows
例えば、500px〜1000pxの範囲にする場合↓
.hoge {
display:grid;
grid-template-columns:repeat(auto-fill,minmax(500px,1000px));
}
注意点
最大サイズが最小サイズより小さい場合、最大サイズの値は無視されます。
minmax(500px,300px) // 300pxは無視。実質minmax(500px,500px)を指定したのと同じ
また、最小値にfr
単位を使用すると無効になります。fr単位は最大値にのみ設定できます。
minmax(1fr,300px) // 無効
fr
単位は、余ったスペースの配分を決めるものです。
min()関数
この関数は、引数としてカンマで区切った 1 つ以上の値を取り、もっとも小さい値を使用します。
min(30px,100px,10px) // 最も小さい10pxが結果として返される
よくwidth
と組み合わせて使用し、最大値を設定させています。
.hoge {
width:min(100%,1200px);//最大値1200px。max-widthを省略できる。
}
サンプルに当てはめて考える
.l-grid {
--minimum: 300px;
display: grid;
grid-template-columns: repeat(auto-fill,minmax(min(var(--minimum), 100%), 1fr));
gap: 1.875rem;
}
列数の決まり方
サンプルの場合の列数の決まり方を解説します。
グリッドコンテナ幅が1200pxのとき
300px(最小トラックサイズ) * 3(列数) + 30px(gap) * 2 = 960px
で幅に収まる最大の数のため、3列になります。
4列の場合、300 * 4 + 30 * 3 = 1290px
でグリッドコンテナの幅1200pxを超えてしまうのでダメです。
グリッドコンテナ幅が600pxのとき
300px * 2 + 30px * 2 = 660px
で幅を超えるので、1列になります。
最小サイズ
min(var(--minimum),100%)
と指定されています。--minimum
の値は300pxです。
このときの%単位はグリッドコンテナを基準にしています。
よってグリッドコンテナ幅が300px以上の時は、300pxが最小サイズです。
300px未満になったとき、100%が最小サイズに選ばれます。
最大サイズ
最大サイズは1frです。
もし、スペースに余りができたとき、列数で割って均等にそのスペースを配分します。
例えば、「グリッドコンテナ幅1400pxで最小サイズが300px」のとき、1400px - (300px * 4 + 30px * 3) = 110px
の余りが出ます。
これを列数4で割って110px / 4 = 27.5px
の27.5pxをそれぞれに配分します。そのため、グリッドトラックサイズは327.5pxになります。
min()関数を使うメリット
min()
関数を使うことで、グリッドコンテナ幅が300px未満になったときでも横スクロールが発生しません。
min()関数を使用しない場合
.l-grid {
--minimum: 300px;
display: grid;
grid-template-columns: repeat(auto-fill,minmax(var(--minimum), 1fr));
gap: 1.875rem;
}
横スクロールが発生しています。
min()関数を使用した場合
.l-grid {
--minimum: 300px;
display: grid;
grid-template-columns: repeat(auto-fill,minmax(min(var(--minimum), 100%), 1fr));
gap: 1.875rem;
}
画面幅に収まっています。
まとめ
以上より、grid-template-columns: repeat(auto-fit, minmax(min(var(--minimum),100%), 1fr));
の意味は、「列数がグリッドコンテナ幅を超えない可能な最大の数で、最小サイズが300px(300px未満の時は100%)、最大サイズが1fr」ということになります。