今日は、これぞcss grid layout を使うべきケースであるレスポンシブなギャラリーのレイアウトを紹介します。おそらく、これまでは flexbox で実装していたレイアウトでしょう。css grid layout を使用することで、 とても簡単に実装できます。そして、モバイル、タブレットなどのレスポンシブ対応に、メディアクエリーすら使う必要がなくなり、コードもだいぶスッキリするはずです。
それでは、初心者向けに詳しく解説していきます。
〜【初心者向け】CSS Gridをマスターするシリーズ〜
Contents
CSS Gridで作成するレスポンシブギャラリーのデモ(完成形)
今回は、よく見かけるであろう、こんなレスポンシブなギャラリーのレイアウトを、css gridを使い実装していきます。css gridを使えば、驚くほど簡単にできてしまいます。
ちゃんとレスポンシブなってますね。オンラインサービスのCodepen上でのdemoですので、少し動きが重たいのは、ご了承ください。
基本となるHTML
まずはHTMLです。先程のデモのように実践的な見た目となるように、それぞれのカード(グリッドアイテム)にコンテンツを入れています。
<div class="grid-container">
<div class="item item__1">
<div>
<img src="http://placekitten.com/300/200" />
</div>
<div>Card-1</div>
<p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s. Hello, my lovely cat.</p>
</div>
<div class="item item__2">
<div>
<img src="http://placekitten.com/300/200" />
</div>
<div>Card-2</div>
<p>Lorem Ipsum is simply dummy text of the printing and typesetting industry.</p>
</div>
<div class="item item__3">
<div>
<img src="http://placekitten.com/300/200" />
</div>
<div>Card-3</div>
<p>Lorem Ipsum is simply dummy text of the printing and typesetting industry.</p>
</div>
<div class="item item__4">
<div>
<img src="http://placekitten.com/300/200" />
</div>
<div>Card-4</div>
<p>Lorem Ipsum is simply dummy text of the printing and typesetting industry.</p>
</div>
<div class="item item__5">
<div>
<img src="http://placekitten.com/300/200" />
</div>
<div>Card-5</div>
<p>Lorem Ipsum is simply dummy.</p>
</div>
</div>
今の状態だと、グリッドレイアウトのHTML構造がわかりにくいので、カード内のコンテンツ部分のHTMLを除いたバージョンも載せておきます。
<div class="grid-container">
<div class="item item__1"></div>
<div class="item item__2"></div>
<div class="item item__3"></div>
<div class="item item__4"></div>
<div class="item item__5"></div>
</div>
カードのコンテンツ部分を省略したHTMLは上記の通りとてもシンプルです。CSS Gridのレスポンシブなギャラリーに必要な部分は、これだけです。
一番外のdivをレスポンシブギャラリーのgird containerに指定して、その中に5つのグリッドアイテムがあるだけの、とてもシンプルなレイアウトです。
基本となるCSS
コード内に出来るだけコメントを追加しているので確認してみてください。
body {
/* プロジェクトセットアップ */
font-size: 30px;
color: white;
}
.grid-container {
background: #cfd8dc;
padding: 30px;
/* 実質、以下の3ラインのコードのみでレスポンシブなギャラリーが実装できます */
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
grid-gap: 30px;
}
/* ここから下はそれぞれのitem、つまりカードに対するスタイリングですので、レスポンシブギャリーとは、直接関係ない CSS です。 */
.item {
background: #2196f3;
padding: 20px;
display: grid;
grid-gap: 10px;
grid-template-columns: 1fr;
grid-template-rows: 250px 50px 1fr;
}
.item > p {
font-size: 12px;
}
.item > div {
width: 100%;
}
.item > div > img {
width: 100%;
height: 100%;
object-fit: cover;
}
上記のデモで使用したCSSの半分以上は、レスポンシブギャラリーではなく、カードの中のコンテンツのスタイリングです。css grid layoutによるレスポンシブギャラリーの実装に必要なCSSは実質、以下の3行のみです。
この3行です。
.grid-container {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
grid-gap: 30px;
}
グリッドレイアウトを使用すれば、たったこれだけのCSSでレスポンシブなギャラリーのレイアウトが完成してしまいます。
メディアクエリーなど一切使っていません。
以下では、今回のcss grid layoutのポイントを解説していきます。
ポイントである repeat() を極める
今回のレスポンシブギャラリーグリッドレイアウトでポイントとなるのは、
grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
の部分です。
ですので、このセクションでは、repeat()の使い方をもう少し詳しく説明します。
repeat()の使い方を理解していなくても、ここまでのコードでレスポンシブギャラリーは簡単に実装できてしまいます。しかし、一度しっかりと理解してしまえば、他の複雑なレイアウトにも応用が可能なパワフルな関数です。フロントエンドエンジニアであれば、絶対に知っておくべき機能です。
ここからは、カードの中身を除いたシンプルなHTMLとCSSを使用していきます。
基準とするHTML
<div class="grid-container">
<div class="item item__1"></div>
<div class="item item__2"></div>
<div class="item item__3"></div>
<div class="item item__4"></div>
<div class="item item__5"></div>
</div>
基準とするCSS
body {
/* プロジェクトセットアップ */
font-size: 30px;
color: white;
}
.grid-container {
background: #cfd8dc;
padding: 30px; /*
実質、以下の3ラインのコードのみでレスポンシブなギャラリーが実装できます */
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
grid-gap: 30px;
}
.item {
background: #2196f3;
min-height: 200px;
}
基準とするcss grid layout のデモ
このcss gird layoutを基準にして、repeat()の引数(指定する値)を変更していき、動きの違いを理解しましょう。
minmax()を解説
ここで、まずは簡単な minmax() のポイントをまとめます。
-
minmax(x, y)
: xが最小値(min) 、yが 最大値(max) の2つの引数を取る関数 - もし最小値(min)が、最大値(max)より大きい場合は無視され、 minmax(min, max) は、最小値(min)として扱われる。
repeat()を解説
repeat() のポイントをまとめます。
- CSS Grid のプロパティである、
grid-template-columns
とgrid-template-rows
のバリュー(値)として使える
repeat(auto-fill, minmax(200px, 1fr))を指定
repeat() 関数内の、第一引数を、auto-fill から auto-fit に変更しましょう。
auto-fill と auto-fit の動きの違いを理解することが大切です。
このデモを見ても明らかなように、違いが出ているのは、デモの最初と最後の部分です。
簡単に動きの違いを説明すると、
auto-fill :グリッドコンテイナーにスペースが余るとき、自動で空のグリッドセルが作られる。
auto-fit:グリッドコンテイナーにスペースが余るとき、自動でグリッドアイテムの幅が調整されスペースを埋めていく。
*注意!逆に、グリッドコンテイナーにスペースが余っていない時には、auto-fillとauto-fitは同じ動作をします。先ほどのデモの通りです。
下の画像のように、auto-fillを指定した方のみ、グリッドコンテイナーのスペースが余るときに、空のグリッドセルが作られているのが確認できます。
では、どのタイミングで空のグリッドが作られのかを、もう少し詳しくみていきましょう。
ここで効いてくるのが、repeat()の第二引数です。僕たちのデモでは、minmax(200px, 1fr)
となっています。
よって、それぞれのグリッドアイテムの幅は、最小値:200px、最大値:1fr(ここでは、全てのグリッドアイテムが同じ幅を持つという意味)である必要があります。
auto-fill を指定した場合には、windowの幅を徐々に広げ、新たに200pxのスペースができた時点で、初めて6つ目の空のグリッドセルが作られます。念の為確認ですが、この例ではもともと5つのグリッドアイテムがあります。また、minmax(200px, 1fr)
の通り、グリッドアイテムの最小値を200pxと指定しています。
6つ目の空のグリッドセルができた時点でのそれぞれのグリッドアイテムの幅を確認すれば、200pxとなっているはずです。
逆に言えば、この例ではグリッドコンテイナーの幅が1410pxになった時点で、6つ目の空のグリッドセルが作られます。6つ目の空のグリッドセルが作られるためには、グリッドコンテイナーの幅が最低でも1410px必要だということです。
計算すると下記のようになります。
1410px(グリッドコンテイナーの幅)
= 30px * 2(padding) + 200px * 5(グリッドアイテム) + 200px(空のグリッドセル) + 30px * 5(グリッド ギャップ)
さらに、1410px + 200px + 30px = 1640px になった時点で、7つ目の空のグリッドセルが作られるはずです。
css gridが入れ子状態となっているカードのスタイリング
ここはおまけのセクションです。css grid layoutのレスポンシブギャラリーとは関係ありません。今回のcss grid layout では、下記の2箇所に display: grid; を指定しています。
- レスポンシブギャラリーのレイアウト(上記で説明済み)
- それぞれのカードの中身のレイアウト
つまり、css grid が入れ子状態となっているだけですので、混乱しないでください。外側から見ると、レスポンシブギャラリーがグリッドコンテナ、それぞれのカードがまたグリッドコンテナとなっています。
グリッドレイアウトの中に、別のグリッドレイアウトが存在している状態です。
まとめ
今回は css gird layoutの実践編として、メディアクエリーを使わないでレスポンシブなギャラリーを実装しました。
僕は最近、仕事のサイトでflexbox layoutから、このcss grid layoutに変更しましたが、HTML, CSS共にかなりコードがスッキリしました。
初心者のかたもガンガン使っていきましょう!
わかりやすかった、分かりにくかった、ココこうした方がいいのでは?などのコメント頂けると、とても嬉しいです。
参考サイト
- CSS Grid Layout Module Level 1(https://www.w3.org/TR/css-grid-1/)
- MDN web docs Grids (https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Grids)
[…] CSS Gridで実装する爆速レスポンシブギャラリー […]
[…] CSS Gridで実装する爆速レスポンシブギャラリー […]