◆ 画像を並べる

画像をキレイに並べたかったのですが 思った以上に苦労したのでメモしておきます
やりたいのは横一列に画像を並べるというもの

縦長や横長など画像サイズはバラバラです
それでも崩れないように高さの最大値ありで 横幅は一列に収まってはみ出すこともないように自動調整です
全体の幅はウィンドウサイズによって変わります

画像数の最大は今回は 5 つにしています
3 つだから ひとつの最大幅は画像一覧の親要素の 33% で 5 のときは 20% というような画像数で最大幅が可変にはせず 5 つに合わせて最大は 20% 固定です
ただ最大幅なので縦長画像で 10% の幅で済むなら 10% の幅にして詰めます
先に 20% ずつの幅を確保してそこに画像をセンタリングで配置とはしません

flexbox を使えば 割と簡単にはなったのですが それでも img タグはいう事聞いてくれない系なので難しかったです
単純に flex コンテナの中に img タグ並べるだけならまだ簡単だったのですが それぞれの img タグを div で包みたいときには特に難しかったです
パーセントみたいな親のサイズを元に子が決まるものと 子のサイズに応じて親のサイズが決まるものが混ざっていたりと考え出すとわからなくなってくるので 結局いろいろプロパティ変えながら試して動くものを見つけた感じです

DEMO

こういう表示です

imgalign

青色四角がそれぞれ画像です
上半分は直接 img タグで
下半分は img を div で包んでます

<!doctype html>

<style>
.img-list {
width: 50%;
margin: 30px auto;
background: #f0f0f0;
border: 1px solid #ddd;
display: flex;
align-items: center;
}

.c1 img {
margin: 0 0 0 10px;
max-width: calc(100% / 5 - 10px - 10px / 5);
max-height: 80px;
object-fit: contain;
}

.c2 .img-container {
max-width: calc(100% / 5 - 10px - 10px / 5);
margin: 0 0 0 10px;
}

.c2 img {
display: block;
max-width: 100%;
max-height: 80px;
object-fit: contain;
}
</style>

<script type="module">
const createImage = ({w, h, c}) => {
const cvs = document.createElement("canvas")
const ctx = cvs.getContext("2d")
cvs.width = w
cvs.height = h
ctx.fillStyle = c
ctx.fillRect(0, 0, w, h)
return cvs.toDataURL()
}

const crim = (w, h) => createImage({w: w || 320, h: h || 100, c: "#cce"})

document.body.innerHTML = `
<div class="img-list c1">
<img src="${crim()}">
<img src="${crim()}">
<img src="${crim()}">
<img src="${crim()}">
<img src="${crim()}">
</div>
<div class="img-list c1">
<img src="${crim(100, 400)}">
<img src="${crim(400, 100)}">
<img src="${crim(200, 200)}">
<img src="${crim(30, 30)}">
<img src="${crim(80, 40)}">
</div>
<div class="img-list c2">
<div class="img-container"><img src="${crim()}"></div>
<div class="img-container"><img src="${crim()}"></div>
<div class="img-container"><img src="${crim()}"></div>
<div class="img-container"><img src="${crim()}"></div>
<div class="img-container"><img src="${crim()}"></div>
</div>
<div class="img-list c2">
<div class="img-container"><img src="${crim(100, 400)}"></div>
<div class="img-container"><img src="${crim(400, 100)}"></div>
<div class="img-container"><img src="${crim(200, 200)}"></div>
<div class="img-container"><img src="${crim(30, 30)}"></div>
<div class="img-container"><img src="${crim(80, 40)}"></div>
</div>
`
</script>

一番困ったのはは max-height は親の img-list につけてもダメで img に付けないとダメというところです
親につけて子は max-height: 100% にしたのですが それだと親サイズをはみ出す画像になりました
この場合は 子を指定して親は子に合わせて自動とするのが正しいみたいです

あとは img タグ自体は縦幅いっぱいでも object-fit: contain で調整されるから問題ないかなと考えていましたが それだと img に border や box-shadow 付ける場合に余白の外側につくことになるので img 自体を最小にする必要がありました
object-fit は一応残してますがはずしても見た目は変わりません(消し忘れともいう)

本題とは関係ないですがここで使ってる createImage 関数はダミー画像作るのにけっこう便利です
canvas を使って指定した幅と高さと背景色の png ファイルを DataURL 形式で出力します