上のgif画像のような、コンテナ幅に合わせてカラム数を勝手に調整してくれるタイルレイアウトを実装してみました。記事一覧とかをレスポンシブにする時に使われるやつです。
実装の方法自体は簡単なもので、
.container{
display: grid;
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}
この二行をコンテナに追加するだけです。しかし、実装はできても、その仕組みのところまで一発で理解することができなかったので、立ち止まって自分なりに整理してみることにしました。
なんでその1 なんでauto-fit?
そもそもauto-fit
ってなんぞ?ってレベルだったので、まずはGoogle検索で調べてみることにしました。すると、大抵の記事でauto-fill
との比較によってauto-fit
を説明していました。
どちらも、repeat()
の第一引数に指定するためのもので、コンテナ幅 / 第二引数の数(小数点以下切り捨て)だけグリッドのカラム(行)を生成するというものです。両者の違いは、以下の点にあります。
auto-fill
余白ができる場合、余白を埋めるためにカラム(行)が追加され、要素がなくてもそのカラム(行)は保持される(画像はgrid-template-columns: repeat(auto-fill, 150px);
とした場合)。
auto-fit
コンテナ幅 / 第二引数の数分のカラム(行)を生成するが、要素がないカラムは自動的に非表示になる(画像はgrid-template-columns: repeat(auto-fit, 150px);
とした場合)。
auto-fit
とauto-fill
の違いについては、既存のソースでも十分に分かりやすかったのですが、むしろ二つの値に共通する、コンテナ幅 / 第二引数という具体的な算出方法が書いてあるソースが、ちょっと探しただけだと見当たらなかったため、理解に至りにくかったように思います。ただこれで、確かにレスポンシブには使いやすそうだなーというのは理解できました。PC幅からスマホ幅に変わればコンテナ幅も大きく変わるため、コンテナ幅 / 第二引数の結果=カラム数が変動するわけですね。
なんでその2 なんでminmax(150px, 1fr)?
私はここがなかなか理解できませんでした。最小値150px
の方はなんとなく分かるけど、最大値が1fr
ってどういうこと??なんでそれであの挙動になるの??って感じでした。
ここは字面だけ眺めていても理解しにくい部分なのかなと思います(私だけかも)。なので、実際に手を動かし、repeat()
の第二引数をminmax(150px, 1fr)
とした場合とそうでない場合を比較してみることにしました。
①grid-template-columns: repeat(auto-fit, 1fr);
とした場合(あんまり意味なさそう)
②grid-template-columns: repeat(auto-fit, 150px);
とした場合
③grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
とした場合
②と③の比較で、各アイテム幅がビヨーンって変化している時間帯に、最大値に指定した1frが適用されているんだなあと、なんとなくですが視覚的に分かりました。そして、もっと細かく見ていくと、②でも③でも、コンテナ内に新しいカラムが生成されるタイミング(コンテナ幅が150n pxになった瞬間)は変わらない、ということも分かりました。
「なんでその1」の内容と合わせて考えると、grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
の処理内容をこんな感じに分解できるはずです。
まず最初に、コンテナ幅 / 150px
によって、auto-fit
のとる値=カラム数が算出される。
↓
カラム数によって、最大値に指定した1fr
の値も決まってくる。
↓
1fr
の値が決まったことで、 minmax(150px, 1fr)
の計算が行われ、各カラムの幅が決定される
例えば、
コンテナが599px
の時は、カラム数が3
で、各カラムの幅は599/3 px(1fr)
となる
コンテナが600px
の時は、カラム数がひとつ増えて4
に、各カラムの幅は150px
となる
コンテナが601px
の時は、カラム数が4
で、各カラムの幅は601/4 px(1fr)
となる
というわけですね。
minmax(固定値,可変値)
の考え方
そして、私はここから、もうひとつ重大な気づきを得ることができました。
私はこれまで、minmax(150px, 1fr)
を「最小値が150pxで、最大値が1fr」とそのまま読み替えていたのですが、これが直感的な理解を妨げる要因となっていたのです。
最大値が可変、って、なんかちょっとイメージしづらくないですか?たとえば、minmax(150px, 200px)
というような、(固定値,固定値)
の組み合わせであれば、(最小値が150px
、最大値が200px
で、その間を行き来するんだな……)と置き換えやすいのですが。
なので、minmax(固定値,可変値)
の場合は、こんな風に言い換えてしまいましょう。
「常に可変値
が適用され、その最小値が固定値
となる」
minmax(150px, 1fr)
の場合ですと、「常に1fr
が適用され、その最小値が150px
となる」となるわけです。これで少し直感的に理解しやすくなったのではないでしょうか?
おわりに
一つの「分からん」から副次的に色々な「分からん」が出てきて、それらも ついでに解消することができたので、やはり立ち止まって(手は動かしながら)考えることは大事だなあと思いました。
ご感想やご指摘などあれば、コメント欄にお書きいただけますと幸いです🙇
参考