サムネイル画像をクリックすると、上に表示されているメイン画像が切り替わるタブの作り方を紹介します。複数の画像を小さなサムネイルとして並べ、見たい画像をクリックするだけで大きく表示できる仕組みです。
今回のデモでは、山と湖・海と青空・森と木々・街並みの4枚の画像を用意しています。サムネイルをクリックすると、対応する画像がメインエリアに表示され、画像名と現在の表示枚数も更新されます。選択中のサムネイルには青い枠線と淡い青色の背景が付き、どの画像を表示しているか一目で分かります。
サムネイルはパソコンでは横4列、スマートフォンでは2列に配置されます。また、キーボードの左右矢印キーでも画像を切り替えられ、Homeキーで最初の画像、Endキーで最後の画像を選択できます。Macでは、Homeキーは「fn + ←」、Endキーは「fn + →」で操作できます。
デモ
山と湖の風景
01 / 04下に並んだサムネイル画像をクリックすると、上のメイン画像が切り替わります。選択したサムネイルには青い枠線が付き、画像名と表示枚数も更新されます。スマートフォンではサムネイルが2列で表示されます。
コードをコピーして使おう!
<!DOCTYPE html>
<html lang="ja">
<head>
<!-- 文字コードの設定 -->
<meta charset="UTF-8">
<!-- スマートフォンなどの画面幅に対応 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- ページタイトル -->
<title>サムネイル画像をクリックして表示を切り替えるタブ</title>
<!-- サムネイル画像切り替えタブのCSSを読み込む -->
<link rel="stylesheet" href="style.css">
</head>
<body>
<!-- サムネイル画像切り替えタブ全体 -->
<div class="thumbnail-tab-switch_container">
<!-- 選択中の画像を大きく表示 -->
<div class="thumbnail-tab-switch_display" id="thumbnail-tab-switch-panel" role="tabpanel" aria-labelledby="thumbnail-tab-switch-tab-1">
<!-- imagesフォルダにimage1.png~image4.pngを用意してください -->
<img class="thumbnail-tab-switch_main-image" id="thumbnail-tab-switch-main" src="images/image1.png" alt="山と湖の風景">
</div>
<!-- 選択中の画像名と枚数 -->
<div class="thumbnail-tab-switch_info">
<p class="thumbnail-tab-switch_caption" id="thumbnail-tab-switch-caption">山と湖の風景</p>
<span class="thumbnail-tab-switch_counter" id="thumbnail-tab-switch-counter">01 / 04</span>
</div>
<!-- 画像を切り替えるサムネイル一覧 -->
<div class="thumbnail-tab-switch_tabs" role="tablist" aria-label="画像の切り替え">
<!-- 1枚目:山と湖 -->
<button class="thumbnail-tab-switch_tab is-active" id="thumbnail-tab-switch-tab-1" type="button" role="tab" aria-controls="thumbnail-tab-switch-panel" aria-selected="true" tabindex="0" data-image="images/image1.png" data-title="山と湖の風景">
<img class="thumbnail-tab-switch_thumbnail" src="images/image1.png" alt="">
<span class="thumbnail-tab-switch_label">山と湖</span>
</button>
<!-- 2枚目:海と青空 -->
<button class="thumbnail-tab-switch_tab" id="thumbnail-tab-switch-tab-2" type="button" role="tab" aria-controls="thumbnail-tab-switch-panel" aria-selected="false" tabindex="-1" data-image="images/image2.png" data-title="海と青空の風景">
<img class="thumbnail-tab-switch_thumbnail" src="images/image2.png" alt="">
<span class="thumbnail-tab-switch_label">海と青空</span>
</button>
<!-- 3枚目:森と木々 -->
<button class="thumbnail-tab-switch_tab" id="thumbnail-tab-switch-tab-3" type="button" role="tab" aria-controls="thumbnail-tab-switch-panel" aria-selected="false" tabindex="-1" data-image="images/image3.png" data-title="森と木々の自然風景">
<img class="thumbnail-tab-switch_thumbnail" src="images/image3.png" alt="">
<span class="thumbnail-tab-switch_label">森と木々</span>
</button>
<!-- 4枚目:街並み -->
<button class="thumbnail-tab-switch_tab" id="thumbnail-tab-switch-tab-4" type="button" role="tab" aria-controls="thumbnail-tab-switch-panel" aria-selected="false" tabindex="-1" data-image="images/image4.png" data-title="街並みと建物">
<img class="thumbnail-tab-switch_thumbnail" src="images/image4.png" alt="">
<span class="thumbnail-tab-switch_label">街並み</span>
</button>
</div>
</div>
<!-- サムネイル画像切り替えタブのJavaScriptを読み込む -->
<script src="script.js"></script>
</body>
</html>
コードをコピーする場合 使用するコードのタブを選び、「このタブをコピー」をクリックすると、現在表示中のコードをコピーできます。 サンプル一式を取得する場合 HTML・CSSなどすべてのファイルが必要な場合は、「サンプル一式をダウンロード」をクリックしてください。
Q ダウンロードしたけど、これをネット上で動かすにはどうするの?
Googleアカウントがあれば、InfinityFreeで無料サーバーを作成して、ダウンロードしたサンプルをネット上で動かせます。
InfinityFreeを初めて利用する場合は①から、すでにサーバーを作成している場合は②へ進んでください。
ファイル構成と設置方法
このサンプルは、HTML・CSS・JavaScriptの3つのファイルで構成されています。 HTMLにメイン画像とサムネイルを配置し、CSSで表示サイズや選択状態を設定します。 JavaScriptでは画像の切り替えとキーボード操作を制御します。 表示に使用する4枚の画像は利用者自身で用意してください。 画像ファイルはZIPには含まれていません。
sample/
├── index.html
├── style.css
├── script.js
└── images/
├── image1.png
├── image2.png
├── image3.png
└── image4.png
各ファイルの役割
index.htmlには、メイン画像、画像名、表示枚数、
4つのサムネイルボタンを配置しています。
各ボタンには、切り替え先の画像パスと画像名を設定しています。
style.cssでは、メイン画像の縦横比、サムネイルの並び、
選択中の枠線や背景色、画面幅に応じたレイアウトを指定しています。
script.jsでは、クリックされた画像への切り替え、
画像名と枚数の更新、選択状態の変更、キーボード操作を処理しています。
imagesフォルダには、利用者が用意する4枚のPNG画像を配置します。
設置方法・使い方
「サンプル一式をダウンロード」からZIPファイルを保存して展開します。
展開したsampleフォルダ内にimagesフォルダを作成し、
4枚のPNG画像をimage1.pngからimage4.pngの名前で保存してください。
画像を配置したらindex.htmlをブラウザで開きます。
サムネイルをクリックすると、対応する画像がメインエリアに表示されます。
キーボード操作は、サムネイルにフォーカスを合わせてから使用してください。
サムネイルと表示画像の設定
index.htmlでは、各ボタンのdata-imageに表示する画像のパス、
data-titleに画像名を設定しています。
ボタン内のimgはサムネイルとして表示する画像です。
<!-- 1枚目:山と湖 -->
<button class="thumbnail-tab-switch_tab is-active" id="thumbnail-tab-switch-tab-1" type="button" role="tab" aria-controls="thumbnail-tab-switch-panel" aria-selected="true" tabindex="0" data-image="images/image1.png" data-title="山と湖の風景">
<img class="thumbnail-tab-switch_thumbnail" src="images/image1.png" alt="">
<span class="thumbnail-tab-switch_label">山と湖</span>
</button>
別の画像へ変更する場合は、data-imageと
サムネイルのsrcを同じ画像パスに変更してください。
data-titleを変更するとメイン画像の名前と代替テキストが変わり、
thumbnail-tab-switch_labelを変更するとサムネイル下の文字が変わります。
初期表示の画像を変更する場合は、メイン画像のsrcとalt、
初期の画像名・枚数、各ボタンの選択状態も合わせて変更します。
クリックした画像へ切り替える仕組み
script.jsのswitchImage()では、
選択されたサムネイルのdata-imageとdata-titleを取得します。
取得した情報をメイン画像と画像名へ反映し、
選択位置から「01 / 04」のような表示枚数を生成します。
// 選択されたサムネイルに設定された画像へ切り替える
mainImage.src = selectedTab.dataset.image;
// メイン画像の代替テキストを更新する
mainImage.alt = selectedTab.dataset.title;
// 画像名を更新する
caption.textContent = selectedTab.dataset.title;
// 現在の画像番号と総枚数を2桁で表示する
counter.textContent =
String(selectedIndex + 1).padStart(2, "0") +
" / " +
String(tabs.length).padStart(2, "0");
selectedIndex + 1は現在の画像番号、
tabs.lengthはサムネイルの総数です。
padStart(2, "0")によって数字を2桁に揃えています。
最初の数値2を変更すると、数字の最小表示桁数を調整できます。
選択中のサムネイルの表示
JavaScriptでは、選択したボタンだけにis-activeクラスを付けます。
同時にaria-selectedとtabIndexを更新し、
選択状態とキーボード操作の対象を一致させています。
// すべてのサムネイルの選択状態を更新する
tabs.forEach(function(tab) {
// 現在のボタンが選択対象か判定する
const isSelected = tab === selectedTab;
// 選択中のボタンだけにis-activeクラスを付ける
tab.classList.toggle("is-active", isSelected);
// アクセシビリティ用の選択状態を更新する
tab.setAttribute("aria-selected", String(isSelected));
// 選択中のボタンだけをTabキーで移動できる対象にする
tab.tabIndex = isSelected ? 0 : -1;
});
選択中のデザインはstyle.cssの
.thumbnail-tab-switch_tab.is-activeで指定しています。
border-colorで枠線の色、
backgroundで背景色、
colorで文字色を変更できます。
/* 選択中のサムネイル */
.thumbnail-tab-switch_tab.is-active {
border-color: #2563eb; /* 選択中の青い枠線 */
background: #eff6ff; /* 選択中の淡い青色の背景 */
color: #1d4ed8; /* 選択中の文字色 */
}
キーボードによる画像の切り替え
script.jsでは、押されたキーに応じて移動先の画像番号を計算しています。
右矢印キーで次の画像、左矢印キーで前の画像へ移動します。
最後の画像から右へ進むと最初へ戻り、最初の画像から左へ進むと最後へ移動します。
HomeキーとEndキーは、それぞれ最初と最後の画像を直接選択します。
// 右矢印キーで次の画像へ移動する
if (event.key === "ArrowRight") {
nextIndex = (index + 1) % tabs.length;
// 左矢印キーで前の画像へ移動する
} else if (event.key === "ArrowLeft") {
nextIndex = (index - 1 + tabs.length) % tabs.length;
// Homeキーで最初の画像へ移動する
} else if (event.key === "Home") {
nextIndex = 0;
// Endキーで最後の画像へ移動する
} else if (event.key === "End") {
nextIndex = tabs.length - 1;
% tabs.lengthは、画像番号を総数の範囲内で循環させるための計算です。
移動先が決まるとswitchImage()で画像を切り替え、
focus()で対象のサムネイルにフォーカスを移します。
メイン画像とサムネイルの表示比率
style.cssでは、メイン画像を16:9、
サムネイルを4:3の縦横比で表示しています。
object-fit: coverにより、画像の縦横比を保ったまま表示領域を埋めます。
aspect-ratioを変更すると表示領域の形が変わり、
画像が切り取られる範囲も変化します。
/* メイン画像 */
.thumbnail-tab-switch_main-image {
display: block; /* 画像下部の余分な隙間をなくす */
width: 100%; /* 表示領域の横幅いっぱいに広げる */
aspect-ratio: 16 / 9; /* 画像の表示比率。16:9に固定する */
object-fit: cover; /* 画像を表示領域いっぱいに収める */
}
/* サムネイル画像 */
.thumbnail-tab-switch_thumbnail {
display: block; /* 画像下部の余分な隙間をなくす */
width: 100%; /* ボタンの横幅いっぱいに広げる */
aspect-ratio: 4 / 3; /* サムネイルの表示比率 */
border-radius: 6px; /* サムネイル画像の角丸 */
object-fit: cover; /* 画像を表示領域いっぱいに収める */
}
レスポンシブ対応
style.cssでは、タブ全体の最大横幅を680pxに設定しています。
画面幅が狭い場合は親要素に合わせて縮小されます。
サムネイルは通常4列ですが、画面幅640px以下では2列になります。
/* サムネイルの並び */
.thumbnail-tab-switch_tabs {
display: grid; /* サムネイルを格子状に配置する */
grid-template-columns: repeat(4, minmax(0, 1fr)); /* PCでは4列に配置する */
gap: 12px; /* サムネイル同士の間隔 */
}
@media (max-width: 640px) {
/* サムネイルを2列にする */
.thumbnail-tab-switch_tabs {
grid-template-columns: repeat(2, minmax(0, 1fr)); /* 2列表示 */
gap: 10px; /* サムネイル同士の間隔 */
}
}
grid-template-columnsのrepeat(4, ...)や
repeat(2, ...)の数値を変更すると、各画面幅での列数を調整できます。
gapを大きくするとサムネイル同士の間隔が広がり、
小さくすると狭くなります。
また、640pxを変更すると2列表示へ切り替わる画面幅を調整できます。
コメント