Webサイトやブログを見ていると、商品画像や作品の紹介で「サムネイルをクリックすると上部の大きな画像が切り替わる」ギャラリー形式をよく見かけますよね。
今回は、上にメイン画像、下にサムネイル画像を4枚配置し、クリックしたサムネイル画像を上部の大きな画像として表示するシンプルな仕組みをHTML・CSS・JavaScriptで実装してみました。
ちょっとしたJavaScriptの知識があれば簡単に再現できますので、初心者の方でも安心して取り組めます。コードもすべて掲載していますので、コピーしてすぐに試すことも可能です!
こんな方におすすめ
商品画像やギャラリーを自作したい方
JavaScriptの基本的な使い方を学びたい方
画像切り替えUIをHTML+CSS+JSで作りたい方
完成イメージ
上部に1枚のメイン画像が表示され、その下に4枚の小さなサムネイル画像が並びます。
サムネイルをクリックすると、上部のメイン画像が切り替わるというシンプルな構造です。

HTMLコード
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<main>
<section>
<div class="images-wrap">
<div class="main-img"><img src="imgs/img-1.JPG"></div>
<ul class="sub-imgs">
<li><img src="imgs/img-1.JPG"></li>
<li><img src="imgs/img-2.JPG"></li>
<li><img src="imgs/img-3.JPG"></li>
<li><img src="imgs/img-4.JPG"></li>
</ul>
</div>
</section>
</main>
<script src="main.js"></script>
</body>
</html>
CSSコード
@charset "utf-8";
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
section {
width: calc(100% - 100px);
max-width: 1500px;
margin: 50px auto;
}
.images-wrap {
max-width: 1000px;
margin: 0 auto;
height: 90vh;
display: grid;
grid-template-rows: 9fr 1fr;
/* display: flex;
flex-direction: column; */
overflow: hidden;
}
.main-img {
width: 100%;
/* height: 75%; */
height: 100%;
overflow: hidden;
}
.main-img img {
width: 100%;
height: 100%;
object-fit: cover;
object-position: center;
vertical-align: bottom;
opacity: 1;
transition: opacity 0.5s ease;
}
.main-img.fade-out {
opacity: 0;
}
.sub-imgs {
display: flex;
width: 100%;
/* height: 25%; */
height: 100%;
}
.sub-imgs li {
flex: 1;
list-style-type: none;
}
.main-img img,
.sub-imgs img {
width: 100%;
height: 100%;
object-fit: cover;
object-position: center;
vertical-align: bottom;
}
.sub-imgs img {
border: 2px solid transparent;
cursor: pointer;
transition: border-color 0.3s;
}
.sub-imgs img.active {
border-color: #fe0404;
filter: blur(2px);
}
JavaScriptコード
const imgtages = document.querySelectorAll('li img');
const mainImg = document.querySelector('.main-img img');
imgtages.forEach((img) => {
img.addEventListener('click', (e) => {
const targetSrc = e.currentTarget.getAttribute('src');
mainImg.classList.add('fade-out');
setTimeout(() => {
mainImg.setAttribute('src', targetSrc);
mainImg.classList.remove('fade-out');
}, 100);
imgtages.forEach(img => img.classList.remove('active'));
e.currentTarget.classList.add('active');
});
});


コメント