たまに見かけるビフォーアフター的なものです。
画像が2枚あって、真ん中のアイコンを横にスライドさせると、写真の表示される範囲が変わるというものを作ります。
目次
実装サンプル
触ってみてください。
他の方のブログを参考にしたり、JSライブラリを使おうとしたのですが、どれもうまくいかず、結果chatGPTに書いてもらいました。
今はなんでもAIで解決できる感じなのですが、一応ブログのネタとして、ここにコードを残しておきます。
スマホでもちゃんと動きます。
HTML
画像のパスは変更してください。
HTML
<section class="image-comparison-slider">
<div class="image-container background-img">
<img src="https://picsum.photos/id/10/800/500" alt="After Image">
<div class="image-label label-after">AFTER</div>
</div>
<div class="image-container foreground-img">
<img src="https://picsum.photos/id/11/800/500" alt="Before Image">
<div class="image-label label-before">BEFORE</div>
</div>
<div class="slider-handle">
<div class="slider-icon">
<span>❮</span><span>❯</span>
</div>
</div>
</section>CSS
CSS
.image-comparison-slider {
position: relative;
width: 100%;
height: 500px;
overflow: hidden;
user-select: none;
margin-bottom: 1.5rem;
touch-action: pan-y;
}
/* 画像コンテナの共通設定 */
.image-comparison-slider .image-container {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
/* 画像伸縮を強制上書き */
.image-comparison-slider .image-container img {
display: block !important;
width: 100% !important;
min-width: 1100px !important;
max-width: 1100px !important;
height: 500px !important;
object-fit: cover !important;
}
/* 前面画像(最初は50%の幅で表示) */
.image-comparison-slider .foreground-img {
width: 50%;
overflow: hidden;
z-index: 2;
}
/* 背景画像 */
.image-comparison-slider .background-img {
z-index: 1;
}
/* 中央のスライダーバー(縦線) */
.image-comparison-slider .slider-handle {
position: absolute;
top: 0;
left: 50%;
width: 4px;
height: 100%;
background-color: #ffffff;
cursor: ew-resize;
z-index: 4;
transform: translateX(-50%);
touch-action: pan-y;
}
/* スライダー中央の丸いアイコン */
.image-comparison-slider .slider-icon {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 40px;
height: 40px;
background-color: #ffffff;
border-radius: 50%;
box-shadow: 0 2px 6px rgba(0,0,0,0.3);
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 6px;
box-sizing: border-box;
color: #555555;
font-size: 12px;
font-weight: bold;
}
/* Before/After ラベルのスタイル */
.image-comparison-slider .image-label {
position: absolute;
top: 15px;
padding: 6px 12px;
background-color: rgba(0, 0, 0, 0.6);
color: #ffffff;
font-size: 14px;
font-weight: bold;
letter-spacing: 1px;
border-radius: 4px;
pointer-events: none; /* ドラッグ操作を邪魔しない */
z-index: 3;
}
.image-comparison-slider .label-before { left: 15px; }
.image-comparison-slider .label-after { right: 15px; }
@media screen and (max-width: 650px) {
.image-comparison-slider {
height: 300px;
}
/* 中の画像を「横幅は画面いっぱい(100vw)、高さは350px」に固定 */
.image-comparison-slider .image-container img {
width: 100vw !important;
min-width: 100vw !important;
max-width: 100vw !important;
height: 300px !important;
}
}Java script
jQueryは使いません。
JavaScript
(function() {
// ページの読み込み完了を待ってから実行
window.addEventListener('DOMContentLoaded', () => {
const currentSection = document.querySelector('.image-comparison-slider');
if (!currentSection) return; // スライダーが存在しないページでは処理をスキップ
const container = currentSection;
const foregroundImg = currentSection.querySelector('.foreground-img');
const handle = currentSection.querySelector('.slider-handle');
let isDragging = false;
// スライダーを動かすメイン関数
function moveSlider(x) {
const rect = container.getBoundingClientRect();
let position = x - rect.left;
// コンテナの範囲内に制限
if (position < 0) position = 0;
if (position > rect.width) position = rect.width;
const percentage = (position / rect.width) * 100;
// 表示の更新
foregroundImg.style.width = `${percentage}%`;
handle.style.left = `${percentage}%`;
}
/* マウス操作 */
handle.addEventListener('mousedown', () => { isDragging = true; });
window.addEventListener('mouseup', () => { isDragging = false; });
window.addEventListener('mousemove', (e) => {
if (!isDragging) return;
moveSlider(e.clientX);
});
/* タッチ操作(スマホ対応) */
handle.addEventListener('touchstart', () => { isDragging = true; });
window.addEventListener('touchend', () => { isDragging = false; });
window.addEventListener('touchmove', (e) => {
if (!isDragging) return;
moveSlider(e.touches[0].clientX);
});
});
})();





