3D表示で中央の画像を強調するスライダーを作る方法
3D表示で中央の画像を強調するスライダーを作る方法を紹介します。このサンプルでは、HTML・CSS・JavaScriptを使用して、中央の画像を大きく表示し、左右の画像を斜めに配置することで立体感のあるスライダーを実装します。左右のボタンをクリックすると画像が1枚ずつ切り替わり、中央へ移動した画像が強調表示されるため、視線を自然に誘導できるデザインを簡単に作成できます。
商品紹介ページのメインビジュアル、制作実績やポートフォリオ、旅行・観光サイトの写真一覧、不動産サイトの物件紹介、キャンペーンページのキービジュアルなど、画像を印象的に見せたい場面で活用できます。左右の画像は少し小さく3D表示されるため、現在表示している画像が分かりやすく、シンプルなスライダーよりも視覚的なインパクトを与えられます。
HTMLでは表示する画像を自由に差し替えることができ、CSSでは画像サイズ、3D回転角度、拡大率、余白、影、角丸などを用途に合わせて変更できます。JavaScriptでは前後の画像切り替えを制御しており、レスポンシブにも対応しているため、スマートフォン・タブレット・PCで利用しやすい3D画像スライダーのサンプルとして活用できます。
コードについて
本記事のコードはサンプルコードです。ご利用前に必ず動作確認を行ってください。
免責事項
本コードの利用により発生した損害について、当サイトは一切の責任を負いません。
デモ
前へ・次へボタンまたはドットをクリックすると、横長画像が無限ループで切り替わり、中央画像が強調表示されます。
コードをコピーして使おう!
<!DOCTYPE html>
<html lang="ja">
<head>
<!-- 文字コード -->
<meta charset="UTF-8">
<!-- スマートフォン対応 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- ページタイトル -->
<title>3D表示で中央の画像を強調するスライダー</title>
<!-- CSSファイル -->
<link rel="stylesheet" href="style.css">
</head>
<body>
<!-- 3D画像スライダー全体 -->
<div class="three-d-center-image-slider_demo">
<!-- 画像表示エリア -->
<div class="three-d-center-image-slider_view">
<!-- 画像を重ねて配置するエリア -->
<div class="three-d-center-image-slider_track">
<!-- 画像1 -->
<div class="three-d-center-image-slider_slide">
<img src="images/image1.jpg" alt="山と湖の風景">
</div>
<!-- 画像2 -->
<div class="three-d-center-image-slider_slide">
<img src="images/image2.jpg" alt="犬の写真">
</div>
<!-- 画像3 -->
<div class="three-d-center-image-slider_slide">
<img src="images/image3.jpg" alt="滝の風景">
</div>
<!-- 画像4 -->
<div class="three-d-center-image-slider_slide">
<img src="images/image4.jpg" alt="岩山の風景">
</div>
<!-- 画像5 -->
<div class="three-d-center-image-slider_slide">
<img src="images/image5.jpg" alt="海辺の風景">
</div>
<!-- 画像6 -->
<div class="three-d-center-image-slider_slide">
<img src="images/image6.jpg" alt="森林の風景">
</div>
</div>
<!-- 前へ・次へボタン -->
<div class="three-d-center-image-slider_buttons">
<!-- 前へボタン -->
<button
class="three-d-center-image-slider_prev"
type="button"
aria-label="前の画像">
前へ
</button>
<!-- 次へボタン -->
<button
class="three-d-center-image-slider_next"
type="button"
aria-label="次の画像">
次へ
</button>
</div>
</div>
<!-- 画像位置を示すドット -->
<div class="three-d-center-image-slider_dots">
<button class="three-d-center-image-slider_dot is-active" type="button" aria-label="1枚目の画像を表示"></button>
<button class="three-d-center-image-slider_dot" type="button" aria-label="2枚目の画像を表示"></button>
<button class="three-d-center-image-slider_dot" type="button" aria-label="3枚目の画像を表示"></button>
<button class="three-d-center-image-slider_dot" type="button" aria-label="4枚目の画像を表示"></button>
<button class="three-d-center-image-slider_dot" type="button" aria-label="5枚目の画像を表示"></button>
<button class="three-d-center-image-slider_dot" type="button" aria-label="6枚目の画像を表示"></button>
</div>
</div>
<!-- JavaScriptファイル -->
<script src="script.js"></script>
</body>
</html>
/* ページ全体 */
body{
margin:0; /* ブラウザ標準の外側余白を削除 */
padding:40px 20px; /* 上下40px・左右20px。値を大きくすると画面端との間隔が広がる */
background:#f8fafc; /* ページ全体の背景色 */
font-family:sans-serif; /* ページ全体で使用するフォント */
}
/* 3D画像スライダー全体と内部要素 */
.three-d-center-image-slider_demo,
.three-d-center-image-slider_demo *{
box-sizing:border-box; /* paddingとborderを横幅や高さへ含める */
}
/* 3D画像スライダー全体 */
.three-d-center-image-slider_demo{
width:100%; /* 画面幅に合わせて横幅を縮小 */
max-width:980px; /* 最大横幅。値を大きくするとスライダー全体が横に広がる */
margin:0 auto; /* 左右中央へ配置 */
}
/* 画像表示エリア */
.three-d-center-image-slider_view{
position:relative; /* ボタンを配置する基準 */
overflow:hidden; /* 表示範囲からはみ出した画像を非表示 */
padding:36px 0 70px; /* 上側36px・下側70pxの余白 */
perspective:1000px; /* 3D表示の奥行き。値を小さくすると立体感が強くなる */
}
/* 画像を重ねて配置するエリア */
.three-d-center-image-slider_track{
position:relative; /* 各画像を配置する基準 */
height:240px; /* 表示エリアの高さ。値を大きくすると縦方向の範囲が広がる */
transform-style:preserve-3d; /* 子要素の3D変形を維持 */
}
/* 各画像 */
.three-d-center-image-slider_slide{
position:absolute; /* すべての画像を同じ領域へ重ねて配置 */
top:0; /* 表示エリアの上端へ配置 */
left:50%; /* 表示エリアの中央を基準に配置 */
width:40%; /* PC表示時の画像幅。値を大きくすると画像が横に広がる */
height:200px; /* PC表示時の画像高さ。値を大きくすると画像が高くなる */
overflow:hidden; /* 角丸からはみ出した画像を非表示 */
border-radius:18px; /* 画像の角丸。値を大きくすると丸みが強くなる */
background:#e0f2fe; /* 画像読み込み前に表示する背景色 */
box-shadow:0 8px 18px rgba(15,23,42,.08); /* 通常時の影 */
opacity:0; /* 初期状態では画像を非表示 */
transform:translateX(-50%) scale(.82); /* 中央を基準に配置して82%へ縮小 */
transition:
transform .55s ease,
opacity .55s ease,
box-shadow .55s ease,
filter .55s ease;
/*
0.55秒で位置・透明度・影・彩度を切り替える。
値を大きくするとゆっくり、小さくすると速く切り替わる。
*/
z-index:0; /* 初期状態の重なり順 */
pointer-events:none; /* 非表示中の画像に対する操作を無効にする */
}
/* 左右画像に重ねる白いベール */
.three-d-center-image-slider_slide::after{
content:""; /* ベール表示用の空要素 */
position:absolute; /* 画像の上へ重ねて配置 */
inset:0; /* 画像全体へ広げる */
background:rgba(255,255,255,.42); /* 白いベール。透明度を大きくすると白っぽくなる */
opacity:0; /* 初期状態ではベールを非表示 */
transition:opacity .55s ease; /* 0.55秒で透明度を切り替える */
pointer-events:none; /* ベールが操作を妨げないようにする */
}
/* スライダー画像 */
.three-d-center-image-slider_slide img{
display:block; /* 画像下部に発生する余白を削除 */
width:100%; /* スライドの横幅いっぱいに表示 */
height:100%; /* スライドの高さいっぱいに表示 */
object-fit:cover; /* 縦横比を保ちながら表示範囲を埋める */
}
/* 左側に表示する画像 */
.three-d-center-image-slider_slide.is-left{
opacity:.9; /* 左画像の透明度 */
transform:
translateX(calc(-50% - 108%))
perspective(1000px)
rotateY(45deg)
scale(.88);
/*
中央から左へ108%移動し、Y軸方向へ45度回転して88%へ縮小する。
45degを大きくすると傾きが強くなる。
*/
filter:saturate(.85); /* 彩度を85%にする */
z-index:1; /* 中央画像より後ろへ配置 */
pointer-events:auto; /* 表示中の画像に対する操作を有効にする */
}
/* 左画像の白いベール */
.three-d-center-image-slider_slide.is-left::after{
opacity:1; /* 白いベールを表示 */
}
/* 中央に表示する画像 */
.three-d-center-image-slider_slide.is-center{
opacity:1; /* 中央画像を完全に表示 */
transform:
translateX(-50%)
rotateY(0deg)
scale(1.08);
/*
中央位置へ配置して108%へ拡大する。
1.08を大きくすると中央画像がさらに強調される。
*/
filter:saturate(1); /* 通常の彩度で表示 */
box-shadow:0 18px 38px rgba(15,23,42,.2); /* 中央画像を強調する影 */
z-index:3; /* 最前面へ配置 */
pointer-events:auto; /* 表示中の画像に対する操作を有効にする */
}
/* 右側に表示する画像 */
.three-d-center-image-slider_slide.is-right{
opacity:.9; /* 右画像の透明度 */
transform:
translateX(calc(-50% + 108%))
perspective(1000px)
rotateY(-45deg)
scale(.88);
/*
中央から右へ108%移動し、Y軸方向へマイナス45度回転して88%へ縮小する。
-45degの絶対値を大きくすると傾きが強くなる。
*/
filter:saturate(.85); /* 彩度を85%にする */
z-index:1; /* 中央画像より後ろへ配置 */
pointer-events:auto; /* 表示中の画像に対する操作を有効にする */
}
/* 右画像の白いベール */
.three-d-center-image-slider_slide.is-right::after{
opacity:1; /* 白いベールを表示 */
}
/* 左側で待機する画像 */
.three-d-center-image-slider_slide.is-hidden-left{
opacity:0; /* 画像を非表示 */
transform:
translateX(calc(-50% - 216%))
rotateY(24deg)
scale(.82);
/* 中央から左へ216%移動して待機させる */
z-index:0; /* 表示中の画像より後ろへ配置 */
}
/* 右側で待機する画像 */
.three-d-center-image-slider_slide.is-hidden-right{
opacity:0; /* 画像を非表示 */
transform:
translateX(calc(-50% + 216%))
rotateY(-24deg)
scale(.82);
/* 中央から右へ216%移動して待機させる */
z-index:0; /* 表示中の画像より後ろへ配置 */
}
/* 前へ・次へボタンエリア */
.three-d-center-image-slider_buttons{
position:absolute; /* 画像表示エリア内へ配置 */
left:0; /* 左端を表示エリアへ合わせる */
right:0; /* 右端を表示エリアへ合わせる */
bottom:0; /* 表示エリアの下端へ配置 */
display:flex; /* ボタンを横並びにする */
justify-content:center; /* ボタンを左右中央へ配置 */
gap:14px; /* ボタン同士の間隔。値を大きくすると広がる */
z-index:5; /* 画像より前面へ配置 */
}
/* 前へ・次へボタン */
.three-d-center-image-slider_buttons button{
position:relative; /* 矢印を配置する基準 */
display:flex; /* 矢印を配置する */
align-items:center; /* 矢印を上下中央へ配置 */
justify-content:center; /* 矢印を左右中央へ配置 */
width:52px; /* ボタンの横幅。値を大きくするとボタンが大きくなる */
height:52px; /* ボタンの高さ。値を大きくするとボタンが大きくなる */
padding:0; /* ブラウザ標準の内側余白を削除 */
border:1px solid #bfdbfe; /* ボタンを囲む枠線 */
border-radius:50%; /* ボタンを円形にする */
background:linear-gradient(135deg,#2563eb,#1e40af); /* ボタンの背景色 */
cursor:pointer; /* マウスを重ねたときに指の形へ変更 */
box-shadow:0 10px 22px rgba(37,99,235,.28); /* ボタンの影 */
transition:
transform .2s ease,
box-shadow .2s ease;
/*
0.2秒で位置と影を切り替える。
値を大きくするとゆっくり、小さくすると速く切り替わる。
*/
font-size:0; /* ボタン内の文字を視覚的に非表示 */
}
/* ボタン内の矢印 */
.three-d-center-image-slider_buttons button::before{
content:""; /* 矢印表示用の空要素 */
width:12px; /* 矢印の横幅 */
height:12px; /* 矢印の高さ */
border-top:3px solid #ffffff; /* 矢印上側の線 */
border-right:3px solid #ffffff; /* 矢印右側の線 */
}
/* 前へボタンの矢印 */
.three-d-center-image-slider_prev::before{
transform:rotate(-135deg); /* 矢印を左向きにする */
margin-left:4px; /* 矢印位置を右へ4px調整 */
}
/* 次へボタンの矢印 */
.three-d-center-image-slider_next::before{
transform:rotate(45deg); /* 矢印を右向きにする */
margin-right:4px; /* 矢印位置を左へ4px調整 */
}
/* ボタンへマウスを重ねたとき */
.three-d-center-image-slider_buttons button:hover{
transform:translateY(-2px); /* ボタンを上へ2px移動 */
box-shadow:0 14px 28px rgba(37,99,235,.35); /* ホバー時の影 */
}
/* 画像位置を示すドットエリア */
.three-d-center-image-slider_dots{
display:flex; /* ドットを横並びにする */
align-items:center; /* ドットを上下中央へ揃える */
justify-content:center; /* ドットを左右中央へ配置 */
gap:10px; /* ドット同士の間隔 */
margin-top:24px; /* ボタンエリアとの間隔 */
}
/* 画像位置を示すドット */
.three-d-center-image-slider_dot{
width:12px; /* ドットの横幅 */
height:12px; /* ドットの高さ */
padding:0; /* 内側余白を削除 */
border:none; /* 枠線を削除 */
border-radius:50%; /* 円形にする */
background:#cbd5e1; /* 通常時の背景色 */
cursor:pointer; /* クリックできることを示す */
transition:
background-color .3s ease,
transform .3s ease;
/*
0.3秒で背景色と大きさを切り替える。
値を大きくするとゆっくり、小さくすると速く切り替わる。
*/
}
/* 選択中のドット */
.three-d-center-image-slider_dot.is-active{
background:#2563eb; /* 選択中の背景色 */
transform:scale(1.2); /* 選択中のドットを120%へ拡大 */
}
/* 画面幅768px以下 */
@media(max-width:768px){
/* 画像を重ねて配置するエリア */
.three-d-center-image-slider_track{
height:220px; /* タブレット表示時の高さ */
}
/* 各画像 */
.three-d-center-image-slider_slide{
width:60%; /* タブレット表示時の画像幅 */
height:180px; /* タブレット表示時の画像高さ */
}
/* 左側に表示する画像 */
.three-d-center-image-slider_slide.is-left{
transform:
translateX(calc(-50% - 58%))
rotateY(18deg)
scale(.9);
/* タブレットでは移動量と傾きを小さくする */
}
/* 右側に表示する画像 */
.three-d-center-image-slider_slide.is-right{
transform:
translateX(calc(-50% + 58%))
rotateY(-18deg)
scale(.9);
/* タブレットでは移動量と傾きを小さくする */
}
/* 左側で待機する画像 */
.three-d-center-image-slider_slide.is-hidden-left{
transform:
translateX(calc(-50% - 130%))
rotateY(18deg)
scale(.82);
}
/* 右側で待機する画像 */
.three-d-center-image-slider_slide.is-hidden-right{
transform:
translateX(calc(-50% + 130%))
rotateY(-18deg)
scale(.82);
}
}
/* 画面幅600px以下 */
@media(max-width:600px){
/* 画像表示エリア */
.three-d-center-image-slider_view{
padding:0 0 70px; /* スマートフォン表示時の余白 */
}
/* 画像を重ねて配置するエリア */
.three-d-center-image-slider_track{
height:190px; /* スマートフォン表示時の高さ */
}
/* 各画像 */
.three-d-center-image-slider_slide{
width:100%; /* スマートフォンでは画像を横幅いっぱいに表示 */
height:180px; /* スマートフォン表示時の画像高さ */
transform:translateX(-50%) scale(1); /* 中央位置へ等倍で配置 */
}
/* 中央以外の画像 */
.three-d-center-image-slider_slide.is-left,
.three-d-center-image-slider_slide.is-right,
.three-d-center-image-slider_slide.is-hidden-left,
.three-d-center-image-slider_slide.is-hidden-right{
opacity:0; /* スマートフォンでは中央以外の画像を非表示 */
transform:translateX(-50%) scale(1); /* 中央位置で待機 */
}
/* 中央に表示する画像 */
.three-d-center-image-slider_slide.is-center{
transform:translateX(-50%) scale(1); /* スマートフォンでは等倍表示 */
}
}
// 3D画像スライダー全体を取得
const threeDCenterImageSlider = document.querySelector(
".three-d-center-image-slider_demo"
);
// すべての画像を取得
const threeDCenterImageSliderSlides =
threeDCenterImageSlider.querySelectorAll(
".three-d-center-image-slider_slide"
);
// 前へボタンを取得
const threeDCenterImageSliderPrev =
threeDCenterImageSlider.querySelector(
".three-d-center-image-slider_prev"
);
// 次へボタンを取得
const threeDCenterImageSliderNext =
threeDCenterImageSlider.querySelector(
".three-d-center-image-slider_next"
);
// すべてのドットを取得
const threeDCenterImageSliderDots =
threeDCenterImageSlider.querySelectorAll(
".three-d-center-image-slider_dot"
);
// 現在中央に表示している画像番号
let threeDCenterImageSliderCurrent = 0;
// 画像の表示位置を更新する関数
function threeDCenterImageSliderDraw(){
// 画像の総数を取得
const total = threeDCenterImageSliderSlides.length;
// 中央画像の左側に表示する画像番号
const leftIndex =
(
threeDCenterImageSliderCurrent
- 1
+ total
) % total;
// 中央画像の右側に表示する画像番号
const rightIndex =
(
threeDCenterImageSliderCurrent
+ 1
) % total;
// すべての画像へ位置用クラスを付け直す
threeDCenterImageSliderSlides.forEach(
function(slide,index){
// 画像のクラスを初期状態へ戻す
slide.className =
"three-d-center-image-slider_slide";
// 中央に表示する画像
if(index === threeDCenterImageSliderCurrent){
slide.classList.add("is-center");
// 左側に表示する画像
}else if(index === leftIndex){
slide.classList.add("is-left");
// 右側に表示する画像
}else if(index === rightIndex){
slide.classList.add("is-right");
// 表示範囲外で待機する画像
}else{
// 現在位置から見た画像の距離を計算
const distance =
(
index
- threeDCenterImageSliderCurrent
+ total
) % total;
// 左側で待機させる画像
if(distance > total / 2){
slide.classList.add(
"is-hidden-left"
);
// 右側で待機させる画像
}else{
slide.classList.add(
"is-hidden-right"
);
}
}
}
);
// 現在の画像に対応するドットを選択状態にする
threeDCenterImageSliderDots.forEach(
function(dot,index){
dot.classList.toggle(
"is-active",
index === threeDCenterImageSliderCurrent
);
}
);
}
// 次へボタンをクリックしたとき
threeDCenterImageSliderNext.addEventListener(
"click",
function(){
// 次の画像番号へ進む
// 最後の画像の次は1枚目へ戻る
threeDCenterImageSliderCurrent =
(
threeDCenterImageSliderCurrent
+ 1
) %
threeDCenterImageSliderSlides.length;
// 画像の表示位置を更新
threeDCenterImageSliderDraw();
}
);
// 前へボタンをクリックしたとき
threeDCenterImageSliderPrev.addEventListener(
"click",
function(){
// 前の画像番号へ戻る
// 1枚目の前は最後の画像へ移動する
threeDCenterImageSliderCurrent =
(
threeDCenterImageSliderCurrent
- 1
+ threeDCenterImageSliderSlides.length
) %
threeDCenterImageSliderSlides.length;
// 画像の表示位置を更新
threeDCenterImageSliderDraw();
}
);
// 各ドットへクリック処理を設定
threeDCenterImageSliderDots.forEach(
function(dot,index){
dot.addEventListener(
"click",
function(){
// クリックしたドットに対応する画像番号へ変更
threeDCenterImageSliderCurrent = index;
// 画像の表示位置を更新
threeDCenterImageSliderDraw();
}
);
}
);
// 初期表示
threeDCenterImageSliderDraw();
コードをコピーする場合
使用するコードのタブを選び、「このタブをコピー」をクリックすると、現在表示中のコードをコピーできます。
サンプル一式を取得する場合
HTML・CSSなどすべてのファイルが必要な場合は、「サンプル一式をダウンロード」をクリックしてください。
ファイル構成と設置方法
このサンプルはHTML・CSS・JavaScriptの3ファイルで構成されています。HTMLでは画像スライダー全体と画像、前へ・次へボタン、ドットナビゲーションを配置し、CSSでは3D表示や中央画像の強調表示、レスポンシブデザインを設定します。JavaScriptでは現在表示中の画像を管理し、左右ボタンやドットクリックに合わせて表示位置を切り替えます。
sample/
├── index.html
├── style.css
├── script.js
└── images/
├── image1.jpg
├── image2.jpg
├── image3.jpg
├── image4.jpg
├── image5.jpg
└── image6.jpg
各ファイルの役割
index.htmlはスライダー全体を構成するファイルです。表示する画像、前へ・次へボタン、ドットナビゲーションを変更できます。
style.cssはスライダーのデザインを設定するファイルです。画像サイズ、3D回転角度、中央画像の拡大率、影、ボタン、ドット、レスポンシブ表示などを変更できます。
script.jsはスライダーの動作を制御するファイルです。左右ボタンやドットクリック時の切り替え処理、中央・左右・待機画像の表示状態を管理します。
設置方法・使い方
sampleフォルダへindex.html、style.css、script.jsを配置し、使用する画像をimagesフォルダへ保存します。HTML内の画像ファイル名を実際のファイル名へ変更したあと、sample/index.htmlをブラウザで開いてください。左右のボタンまたはドットをクリックすると、中央画像を強調した3Dスライダーを操作できます。
カスタマイズできる内容
index.htmlでは画像ファイル、alt属性、画像枚数を変更できます。
style.cssでは画像の横幅・高さ、3D回転角度、中央画像の拡大率、影、角丸、背景色、ボタン、ドット、アニメーション速度などを用途に合わせて調整できます。
script.jsでは初期表示位置やドット・ボタンによる切り替え処理を変更できます。
数値調整
style.css
max-width:980px;
スライダー全体の最大横幅です。値を大きくすると全体が横に広がり、小さくするとコンパクトになります。
width:40%;
各画像の横幅です。値を大きくすると中央画像・左右画像とも大きく表示されます。
height:200px;
画像の高さです。値を変更すると表示される画像の縦サイズが変わります。
rotateY(45deg)
左右画像の3D回転角度です。値を大きくすると立体感が強くなり、小さくすると正面に近い表示になります。
scale(1.08)
中央画像の拡大率です。値を大きくすると中央画像がより強調され、小さくすると控えめになります。
transition:.55s;
スライド切り替え時間です。値を大きくするとゆっくり、小さくすると素早く切り替わります。
レスポンシブ対応
このサンプルはレスポンシブ対応です。style.cssではmedia queryを使用し、768px以下では画像サイズや3D表示を調整し、600px以下では中央画像のみを表示するレイアウトへ切り替えています。そのため、スマートフォン・タブレット・PCでも見やすく利用できます。
コメント