1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

auto-fit/fillでレスポンシブなタイルレイアウトにするやつの理解

Posted at

CleanShot 2024-08-29 at 12.23.05.gif

上の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
CleanShot 2024-08-27 at 17.38.52@2x.png
余白ができる場合、余白を埋めるためにカラム(行)が追加され、要素がなくてもそのカラム(行)は保持される(画像はgrid-template-columns: repeat(auto-fill, 150px);とした場合)。

auto-fit
CleanShot 2024-08-27 at 17.39.38@2x.png
コンテナ幅 / 第二引数の数分のカラム(行)を生成するが、要素がないカラムは自動的に非表示になる(画像はgrid-template-columns: repeat(auto-fit, 150px);とした場合)。

auto-fitauto-fillの違いについては、既存のソースでも十分に分かりやすかったのですが、むしろ二つの値に共通する、コンテナ幅 / 第二引数という具体的な算出方法が書いてあるソースが、ちょっと探しただけだと見当たらなかったため、理解に至りにくかったように思います。ただこれで、確かにレスポンシブには使いやすそうだなーというのは理解できました。PC幅からスマホ幅に変わればコンテナ幅も大きく変わるため、コンテナ幅 / 第二引数の結果=カラム数が変動するわけですね。

なんでその2 なんでminmax(150px, 1fr)?

私はここがなかなか理解できませんでした。最小値150pxの方はなんとなく分かるけど、最大値が1frってどういうこと??なんでそれであの挙動になるの??って感じでした。
ここは字面だけ眺めていても理解しにくい部分なのかなと思います(私だけかも)。なので、実際に手を動かし、repeat()の第二引数をminmax(150px, 1fr)とした場合とそうでない場合を比較してみることにしました。

grid-template-columns: repeat(auto-fit, 1fr);とした場合(あんまり意味なさそう)
CleanShot 2024-08-27 at 18.27.03.gif

grid-template-columns: repeat(auto-fit, 150px);とした場合
CleanShot 2024-08-27 at 18.28.27.gif

grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));とした場合
CleanShot 2024-08-27 at 18.24.52.gif

②と③の比較で、各アイテム幅がビヨーンって変化している時間帯に、最大値に指定した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となる」となるわけです。これで少し直感的に理解しやすくなったのではないでしょうか?

おわりに

一つの「分からん」から副次的に色々な「分からん」が出てきて、それらも ついでに解消することができたので、やはり立ち止まって(手は動かしながら)考えることは大事だなあと思いました。
ご感想やご指摘などあれば、コメント欄にお書きいただけますと幸いです🙇

参考

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?