つくるもの
- 同じ幅・高さを持った要素を左から順に横並びに配置する
- 配置するコンテナの横幅は可変(ウインドウ幅に応じて可変する)
- 横幅いっぱいまで配置したら、行落ちしてまた左から順に横並びに配置する
- リスト全体はその親要素の中央に配置する
- 要素の数は可変である
(クリスマスっぽくて綺麗ですね)
一覧画面などで、情報をカードUIに集約して並べていくものを想像していただくとわかりやすいかなと思います。
こういった場合、 flex
を使うか grid
を使うかで悩むかもしれません。
flexで作ってみる
私は flex
に慣れているので、 flex
で作ろうとしました。
しかし、幅や要素数が可変であるということに、 flex
だと中央配置や、1行あたりの最大配置数に満たない行が出ると期待した配置になりませんでした。
(クリスマスツリーみたいですね)
gridでつくってみる
grid
はこういったケースにとても相性が良いです。
まず、 display: grid
を記述します。
+ .list {
+ display: grid;
+ }
次に、繰り返す要素の幅と高さを定義します。
今回はHTMLとCSSだけの例なので、カスタムプロパティを使用します。
+ :root {
+ --height: 32px;
+ --width: 128px;
+ }
.list {
display: grid;
}
次に、中のグリッドがどのようなルールで作られるのかを記述します。
:root {
--height: 32px;
--width: 128px;
}
.list {
display: grid;
+ grid-template-rows: repeat(auto-fill, var(--height));
+ grid-template-columns: repeat(auto-fill, var(--width));
}
今回は、「同じ幅・高さを持った要素」を並べるので、行方向・列方向ともに固定の幅・高さの繰り返しとなります。
そのため、 grid-template-rows
grid-template-columns
プロパティにそれぞれ repeat(auto-fill, var(--some-value))
を指定しています。
repeat()
は、 grid-template-columns
と grid-template-rows
の中で使うことができる関数で、 1つ目に auto-fill
を指定すると、 2つ目に指定した値を繰り返す場合に、グリッドコンテナをはみ出ない最大の繰り返し値に置き変わります。
あとは、要素の間隔を、 gap
で記述します。
:root {
--height: 32px;
--width: 128px;
+ --gap: 8px;
}
.list {
display: grid;
grid-template-rows: repeat(auto-fill, var(--height));
grid-template-columns: repeat(auto-fill, var(--width));
+ gap: var(--gap);
}
最後に、地味な要件( 私が flex
で作り得なかった要因)である、リスト全体を親要素から見て中央に配置するための記述を追加します。
:root {
--height: 32px;
--width: 128px;
--gap: 8px;
}
.list {
display: grid;
grid-template-rows: repeat(auto-fill, var(--height));
grid-template-columns: repeat(auto-fill, var(--width));
gap: var(--gap);
+ justify-content: center;
}
これで、可変幅でも表示できる最大の数の要素が横並びになりつつ、行落ちした要素も左寄せで表示がされるようになりました。
さいごに
触っていただけるサンプルをこちらに置いておきます。参考になれば幸いです。