はじめに
画像ギャラリーをgridで実装しました。
7枚の画像が不揃いに並んでいるレイアウトです。
デザインカンプに準じて、
①gridを使う、
②画像の増減でレイアウト崩れしないように、
という指示のもと行ったコーディングです。
「画像が不揃い」というだけでも難しかったのですが、
「画像の増減でレイアウトが崩れないようにする」というのがさらに難しく、時間がかかりました。
その時のコードを見直し、違いを比較してみました。
読者対象
・HTML/CSSでコーディングをしている人
・gridレイアウトに不慣れな人
開発環境
用意するファイルはindex.htmlとstyle.cssです。
index.htmlからstyle.cssを読み込みます。
実装手順
・gridで画像を不揃いに並べる。
・画像の増減でレイアウトが崩れないようにする。
gridで画像を不揃いに並べる
HTML
HTMLは非常にシンプルで、画像を囲む親要素がひとつあればOKです。
HTMLで多くの要素を作らなくて済むのは、gridを使うメリットの一つです。
<div class="gallery">
<img src="" alt="" width="" height="">
<img src="" alt="" width="" height="">
<img src="" alt="" width="" height="">
<img src="" alt="" width="" height="">
<img src="" alt="" width="" height="">
<img src="" alt="" width="" height="">
<img src="" alt="" width="" height="">
</div>
最初のCSS
.gallery {
max-width: 500px;
width: 100%;
margin-inline: auto;
/* 以下gridレイアウト用 */
display: grid;
gap: 10px;/* 画像間の余白 */
grid-auto-flow: dense; /* 隙間を埋めながら配置 */
grid-template-columns: repeat(7, 1fr); /* カラム数を設定 */
}
img:first-child {
grid-column: 1/4;
grid-row: 1/3;
}
img:nth-child(2) {
grid-column: 4/8;
grid-row: 1/2;
}
img:nth-child(3) {
grid-column: 4/8;
grid-row: 2/3;
}
img:nth-child(4) {
grid-column: 1/5;
grid-row: 3/5;
}
img:nth-child(5) {
grid-column: 1/5;
grid-row: 5/7;
}
img:nth-child(6) {
grid-column: 5/8;
grid-row: 3/4;
}
img:nth-child(7) {
grid-column: 5/8;
grid-row: 4/7;
}
/* アスペクト比設定 */
img {
display: block;
aspect-ratio: 300/200;
width: 100%;
height: 100%;
object-fit: cover;
}
img:first-child {
aspect-ratio: 200/400;
width: 100%;
height: 100%;
object-fit: cover;
}
img:nth-child(7) {
aspect-ratio: 200/300;
width: 100%;
height: 100%;
object-fit: cover;
}
各画像:nth-child(n)
に、
grid-column: ○/○;
grid-row: ○/○;
で、画像が並ぶ位置を指定しました。
結果
8枚目以降の画像には何も指定をしていないため、画像が増えたとき、一つ分のグリッドセルに自動配置されてしまいました。
この書き方で画像が増えても崩れないようにするためには、:nth-child(8)
、:nth-child(9)
、:nth-child(10)
・・・と、CSSを永遠に用意しておかなければならず現実的ではありません。(※「画像が絶対に増えない」と決まっている場合は、ここまでのコードで完成としても問題ないと思います!)
画像の増減でレイアウトが崩れないようにする
まず、:nth-child(n)
を見直す必要がありました。
:nth-child(n)
から:nth-child(7n+1)
、:nth-child(7n+2)
・・・と変更しました。
すると、、、
8枚目が1枚目に、9枚目が2枚目に、10枚目が3枚目に置き換わってしまいました。
このように置き換わったことで、
grid-column: 1/4;
grid-row: 1/3;
↑この書き方は絶対値での書き方であることが分かりました。
ということで、
grid-column: ○/○;
grid-row: ○/○;
これらをすべて相対値で書き直します。
相対値にはspanを使います。
修正後のCSS
img:nth-child(7n+1) {
grid-column: span 3;
grid-row: span 2;
}
img:nth-child(7n+2),
img:nth-child(7n+3) {
grid-column: span 4;
grid-row: span 1;
}
img:nth-child(7n+4) {
grid-column: span 4;
grid-row: span 2;
}
img:nth-child(7n+5) {
grid-column: span 4;
grid-row: span 2;
}
img:nth-child(7n+6) {
grid-column: span 3;
grid-row: span 1;
}
img:nth-child(7n+7) {
grid-column: span 3;
grid-row: span 3;
}
コードのちがい
img:first-child {
grid-column: 1/4;
grid-row: 1/3;
}
上記の書き方は、グリッドラインと呼ばれるラインの数字を指定します。
grid-column: 1/4;
は「グリッドライン1からグリッドライン4まで」という意味です。(columnなら横方向→、rowなら縦方向↓にカウント)
img:first-child {
grid-column: span 3;
grid-row: span 2;
}
spanを使った書き方では、グリッドセルの数を指定します。
grid-column: span 3;
は「グリッドセル3つ分」という意味です。(columnなら横方向→、rowなら縦方向↓にカウント)
結果
これで、8枚目以降の画像も、表示崩れすることなく表示されるようになりました!!
(画像のアスペクト比も設定していますので、サイズの違う画像を入れても崩れることはありません。)
今回のように要素の増減を考慮しておく必要がある場合は、相対値での実装が適していることがわかりました!!
最後に
今回はgridレイアウト+spanを使うことで「画像の増減でレイアウトが崩れないように」実装できました。
制作当時はヒントをもらいながら実装したものでしたが、今回改めて振り返って自分で言語化してみることでコードの違いを理解することができました。
参考文献
gridの基本概念
参考
フリー画像