3D表示で中央の画像を強調するカルーセルを作る方法
3D表示で中央の画像を強調するカルーセルを作る方法を紹介します。このサンプルでは、HTML・CSS・JavaScriptのみを使用して、中央の画像を大きく表示し、左右の画像を奥行きのある3D表現で配置するカルーセルを作成します。前へ・次へボタンをクリックすると画像がスライドし、中央の画像が切り替わるたびに立体感のある表示を確認できます。
商品紹介、制作実績、ギャラリー、旅行写真、ポートフォリオなど、複数の画像を印象的に見せたい場面で活用できます。中央の画像は拡大表示と影によって強調され、左右の画像はY軸方向へ回転して奥行きを演出するため、一般的なカルーセルよりも視線を中央へ集めやすいデザインです。外部ライブラリは使用せず、JavaScriptだけで画像の表示位置を切り替えています。
HTMLでは画像やalt属性を変更でき、CSSでは画像サイズ、回転角度、拡大率、影、角丸、アニメーション速度などを調整できます。JavaScriptでは表示順を切り替える処理を行っており、画像枚数を増減しても利用できます。レスポンシブにも対応しているため、スマートフォン・タブレット・PCで利用しやすい3Dカルーセルのサンプルとして活用できます。
コードについて
本記事のコードはサンプルコードです。ご利用前に必ず動作確認を行ってください。
免責事項
本コードの利用により発生した損害について、当サイトは一切の責任を負いません。
デモ
「前へ」「次へ」をクリックすると横長の画像が切り替わり、中央の画像が拡大表示され、左右の画像は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-carousel_demo">
<!-- 画像表示エリア -->
<div class="three-d-center-image-carousel_view">
<!-- 画像を重ねて配置するエリア -->
<div class="three-d-center-image-carousel_track">
<!-- 画像1:imagesフォルダに配置した画像ファイル名へ変更 -->
<div class="three-d-center-image-carousel_slide">
<img src="images/【配置した画像のファイル名1】" alt="画像1">
</div>
<!-- 画像2:imagesフォルダに配置した画像ファイル名へ変更 -->
<div class="three-d-center-image-carousel_slide">
<img src="images/【配置した画像のファイル名2】" alt="画像2">
</div>
<!-- 画像3:imagesフォルダに配置した画像ファイル名へ変更 -->
<div class="three-d-center-image-carousel_slide">
<img src="images/【配置した画像のファイル名3】" alt="画像3">
</div>
<!-- 画像4:imagesフォルダに配置した画像ファイル名へ変更 -->
<div class="three-d-center-image-carousel_slide">
<img src="images/【配置した画像のファイル名4】" alt="画像4">
</div>
<!-- 画像5:imagesフォルダに配置した画像ファイル名へ変更 -->
<div class="three-d-center-image-carousel_slide">
<img src="images/【配置した画像のファイル名5】" alt="画像5">
</div>
<!-- 画像6:imagesフォルダに配置した画像ファイル名へ変更 -->
<div class="three-d-center-image-carousel_slide">
<img src="images/【配置した画像のファイル名6】" alt="画像6">
</div>
</div>
</div>
<!-- 前へ・次へボタン -->
<div class="three-d-center-image-carousel_buttons">
<!-- 前へボタン -->
<button
type="button"
id="three-d-center-image-carousel-prev"
aria-label="前へ">
前へ
</button>
<!-- 次へボタン -->
<button
type="button"
id="three-d-center-image-carousel-next"
aria-label="次へ">
次へ
</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-carousel_demo{
width:100%; /* 画面幅に合わせて横幅を縮小 */
max-width:980px; /* 最大横幅。値を大きくするとカルーセル全体が横に広がる */
margin:0 auto; /* 左右中央へ配置 */
box-sizing:border-box; /* paddingとborderを横幅へ含める */
}
/* 画像表示エリア */
.three-d-center-image-carousel_view{
position:relative; /* 内部要素を配置する基準 */
overflow:hidden; /* 表示範囲からはみ出した画像を非表示 */
padding:36px 0 18px; /* 上側36px・下側18pxの余白。値を大きくすると表示エリアが広がる */
perspective:1000px; /* 3D表示の奥行き。値を小さくすると立体感が強くなる */
}
/* 画像を重ねて配置するエリア */
.three-d-center-image-carousel_track{
position:relative; /* 各画像を配置する基準 */
height:240px; /* 表示エリアの高さ。値を大きくすると縦方向の範囲が広がる */
transform-style:preserve-3d; /* 子要素の3D変形を維持 */
}
/* 各画像 */
.three-d-center-image-carousel_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-carousel_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-carousel_slide img{
display:block; /* 画像下部に発生する余白を削除 */
width:100%; /* スライドの横幅いっぱいに表示 */
height:100%; /* スライドの高さいっぱいに表示 */
object-fit:cover; /* 縦横比を保ちながら表示範囲を埋める */
}
/* 左側に表示する画像 */
.three-d-center-image-carousel_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-carousel_slide.is-left::after{
opacity:1; /* 白いベールを表示 */
}
/* 中央に表示する画像 */
.three-d-center-image-carousel_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-carousel_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-carousel_slide.is-right::after{
opacity:1; /* 白いベールを表示 */
}
/* 左側で待機する画像 */
.three-d-center-image-carousel_slide.is-hidden-left{
opacity:0; /* 画像を非表示 */
transform:
translateX(calc(-50% - 216%))
rotateY(24deg)
scale(.82);
/*
中央から左へ216%移動して待機させる。
移動量を大きくすると表示範囲からさらに離れる。
*/
z-index:0; /* 表示中の画像より後ろへ配置 */
}
/* 右側で待機する画像 */
.three-d-center-image-carousel_slide.is-hidden-right{
opacity:0; /* 画像を非表示 */
transform:
translateX(calc(-50% + 216%))
rotateY(-24deg)
scale(.82);
/*
中央から右へ216%移動して待機させる。
移動量を大きくすると表示範囲からさらに離れる。
*/
z-index:0; /* 表示中の画像より後ろへ配置 */
}
/* 前へ・次へボタンエリア */
.three-d-center-image-carousel_buttons{
display:flex; /* ボタンを横並びにする */
justify-content:center; /* ボタンを左右中央へ配置 */
gap:14px; /* ボタン同士の間隔。値を大きくすると間隔が広がる */
margin-top:8px; /* 画像とボタンの間隔。値を大きくすると離れる */
}
/* 前へ・次へボタン */
.three-d-center-image-carousel_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-carousel_buttons button::before{
content:""; /* 矢印表示用の空要素 */
width:12px; /* 矢印の横幅。値を大きくすると矢印が大きくなる */
height:12px; /* 矢印の高さ。値を大きくすると矢印が大きくなる */
border-top:3px solid #ffffff; /* 矢印上側の線 */
border-right:3px solid #ffffff; /* 矢印右側の線 */
}
/* 前へボタンの矢印 */
#three-d-center-image-carousel-prev::before{
transform:rotate(-135deg); /* 矢印を左向きにする */
margin-left:4px; /* 矢印の表示位置を右へ4px調整 */
}
/* 次へボタンの矢印 */
#three-d-center-image-carousel-next::before{
transform:rotate(45deg); /* 矢印を右向きにする */
margin-right:4px; /* 矢印の表示位置を左へ4px調整 */
}
/* ボタンへマウスを重ねたとき */
.three-d-center-image-carousel_buttons button:hover{
transform:translateY(-2px); /* ボタンを上へ2px移動 */
box-shadow:0 14px 28px rgba(37,99,235,.35); /* ホバー時の影 */
}
/* 画面幅768px以下 */
@media(max-width:768px){
/* 画像を重ねて配置するエリア */
.three-d-center-image-carousel_track{
height:220px; /* タブレット表示時の高さ */
}
/* 各画像 */
.three-d-center-image-carousel_slide{
width:60%; /* タブレット表示時の画像幅 */
height:180px; /* タブレット表示時の画像高さ */
}
/* 左側に表示する画像 */
.three-d-center-image-carousel_slide.is-left{
transform:
translateX(calc(-50% - 58%))
rotateY(18deg)
scale(.9);
/* タブレットでは移動量と傾きを小さくする */
}
/* 右側に表示する画像 */
.three-d-center-image-carousel_slide.is-right{
transform:
translateX(calc(-50% + 58%))
rotateY(-18deg)
scale(.9);
/* タブレットでは移動量と傾きを小さくする */
}
/* 左側で待機する画像 */
.three-d-center-image-carousel_slide.is-hidden-left{
transform:
translateX(calc(-50% - 130%))
rotateY(18deg)
scale(.82);
}
/* 右側で待機する画像 */
.three-d-center-image-carousel_slide.is-hidden-right{
transform:
translateX(calc(-50% + 130%))
rotateY(-18deg)
scale(.82);
}
}
/* 画面幅600px以下 */
@media(max-width:600px){
/* 画像表示エリア */
.three-d-center-image-carousel_view{
padding:0; /* スマートフォンでは外側余白を削除 */
}
/* 画像を重ねて配置するエリア */
.three-d-center-image-carousel_track{
height:190px; /* スマートフォン表示時の高さ */
}
/* 各画像 */
.three-d-center-image-carousel_slide{
width:100%; /* スマートフォンでは画像を横幅いっぱいに表示 */
height:180px; /* スマートフォン表示時の画像高さ */
transform:translateX(-50%) scale(1); /* 中央位置へ等倍で配置 */
}
/* 中央以外の画像 */
.three-d-center-image-carousel_slide.is-left,
.three-d-center-image-carousel_slide.is-right,
.three-d-center-image-carousel_slide.is-hidden-left,
.three-d-center-image-carousel_slide.is-hidden-right{
opacity:0; /* スマートフォンでは中央以外の画像を非表示 */
transform:translateX(-50%) scale(1); /* 中央位置で待機 */
}
/* 中央に表示する画像 */
.three-d-center-image-carousel_slide.is-center{
transform:translateX(-50%) scale(1); /* スマートフォンでは等倍表示 */
}
}
// スライド画像一覧を取得
const threeDCenterImageCarouselSlides = document.querySelectorAll(
".three-d-center-image-carousel_slide"
);
// 前へボタンを取得
const threeDCenterImageCarouselPrev = document.getElementById(
"three-d-center-image-carousel-prev"
);
// 次へボタンを取得
const threeDCenterImageCarouselNext = document.getElementById(
"three-d-center-image-carousel-next"
);
// 現在中央に表示している画像番号
let threeDCenterImageCarouselCurrent = 0;
// スライドの表示状態を更新する
function threeDCenterImageCarouselDraw(){
// 画像の総数
const total = threeDCenterImageCarouselSlides.length;
// 左右へ表示する画像番号
const leftIndex =
(threeDCenterImageCarouselCurrent - 1 + total) % total;
const rightIndex =
(threeDCenterImageCarouselCurrent + 1) % total;
// すべての画像を更新
threeDCenterImageCarouselSlides.forEach(function(slide,index){
// 位置クラスを初期化
slide.className =
"three-d-center-image-carousel_slide";
// 中央画像
if(index === threeDCenterImageCarouselCurrent){
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 - threeDCenterImageCarouselCurrent + total) % total;
// 左側で待機
if(distance > total / 2){
slide.classList.add("is-hidden-left");
// 右側で待機
}else{
slide.classList.add("is-hidden-right");
}
}
});
}
// 次へボタン
threeDCenterImageCarouselNext.addEventListener(
"click",
function(){
// 次の画像へ切り替える
threeDCenterImageCarouselCurrent =
(threeDCenterImageCarouselCurrent + 1) %
threeDCenterImageCarouselSlides.length;
// 表示を更新
threeDCenterImageCarouselDraw();
}
);
// 前へボタン
threeDCenterImageCarouselPrev.addEventListener(
"click",
function(){
// 前の画像へ切り替える
threeDCenterImageCarouselCurrent =
(
threeDCenterImageCarouselCurrent - 1 +
threeDCenterImageCarouselSlides.length
) %
threeDCenterImageCarouselSlides.length;
// 表示を更新
threeDCenterImageCarouselDraw();
}
);
// 初期表示
threeDCenterImageCarouselDraw();
コードをコピーする場合
使用するコードのタブを選び、「このタブをコピー」をクリックすると、現在表示中のコードをコピーできます。
サンプル一式を取得する場合
HTML・CSSなどすべてのファイルが必要な場合は、「サンプル一式をダウンロード」をクリックしてください。
ファイル構成と設置方法
このサンプルはHTML・CSS・JavaScriptの3ファイルで構成されています。HTMLではカルーセル全体と画像を配置し、CSSでは3D表示や中央画像の強調表示、左右画像の回転やレスポンシブ対応を設定しています。JavaScriptでは前へ・次へボタンの操作に合わせて表示位置を切り替え、中央画像を基準に左右の画像を3D表示するカルーセルを実現しています。
sample/
├── index.html
├── style.css
├── script.js
└── images/
├── image1.jpg
├── image2.jpg
├── image3.jpg
├── image4.jpg
├── image5.jpg
└── image6.jpg
各ファイルの役割
index.htmlはカルーセル全体を構成するファイルです。表示する画像、画像枚数、代替テキスト、前へ・次へボタンを編集できます。画像はsample/imagesフォルダへ配置し、ファイル名を書き換えるだけで利用できます。
style.cssはカルーセルのデザインを設定するファイルです。画像サイズ、3D回転の角度、中央画像の拡大率、余白、影、角丸、ボタンのデザイン、レスポンシブ表示などを変更できます。
script.jsはカルーセルの動作を制御するファイルです。前へ・次へボタンの処理や中央・左右・待機画像の表示位置を切り替えています。
設置方法・使い方
sampleフォルダへindex.html、style.css、script.jsを配置し、画像はsample/imagesフォルダへ保存します。index.html内の画像ファイル名を実際のファイル名へ変更したあと、sample/index.htmlをブラウザで開くと利用できます。前へ・次へボタンを押すと画像が切り替わり、中央画像が強調表示された3Dカルーセルを確認できます。
カスタマイズできる内容
index.htmlでは表示する画像、画像枚数、alt属性を変更できます。用途に合わせて商品画像、制作実績、観光写真、ギャラリーなどへ利用できます。
style.cssでは画像サイズ、中央画像の拡大率、左右画像の3D回転角度、透明度、影、角丸、ボタンのサイズや色、カルーセル全体の余白などを自由に調整できます。
script.jsでは初期表示する画像や画像の切り替え順を変更できます。
数値調整
style.css
max-width:980px;
カルーセル全体の最大横幅です。値を大きくすると全体が横へ広がり、小さくするとコンパクトになります。
height:260px;
表示エリアの高さです。値を大きくすると画像表示エリアが高くなります。
width:31%;
PC表示時の画像幅です。値を大きくすると画像が大きく表示されます。
height:240px;
画像の高さです。値を変更すると画像の縦サイズが変わります。
perspective:1000px;
3D表示の奥行きです。値を小さくすると立体感が強くなり、大きくすると自然な見た目になります。
rotateY(45deg)
左右画像の回転角度です。値を大きくすると斜め向きが強くなり、小さくすると正面に近づきます。
scale(1.08)
中央画像の拡大率です。値を大きくすると中央画像がより強調され、小さくすると他の画像との差が少なくなります。
transition:.55s;
画像が切り替わるアニメーション時間です。値を大きくするとゆっくり、小さくすると素早く切り替わります。
レスポンシブ対応
このサンプルはレスポンシブ対応です。style.cssのwidth:31%やメディアクエリにより、タブレットでは画像サイズと回転角度を調整し、スマートフォンでは中央画像のみを表示するレイアウトへ切り替わります。そのため、スマートフォン・タブレット・PCのいずれでも見やすく利用できます。
コメント