Welcome to this tutorial on Image Comparison Slider.

HTML Structure

<div class="comparison-slider">
  <img src="https://images.unsplash.com/photo-1542224566-6e85f2e6772f?auto=format&fit=crop&w=800&q=80" alt="Before">
  <div class="comparison-overlay" id="overlay">
    <img src="https://images.unsplash.com/photo-1542224566-6e85f2e6772f?auto=format&fit=crop&w=800&q=80&sat=-100" alt="After (Grayscale)">
  </div>
  <div class="comparison-handle" id="handle">
    <div class="handle-line"></div>
    <div class="handle-button">
      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="15 18 9 12 15 6"></polyline></svg>
      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"></polyline></svg>
    </div>
  </div>
</div>

CSS Styling

body { margin: 0; padding: 0; display: flex; justify-content: center; align-items: center; min-height: 100vh; background-color: #111; font-family: 'Inter', sans-serif;}
.comparison-slider {
  position: relative;
  width: 100%;
  max-width: 800px;
  height: 500px;
  overflow: hidden;
  border-radius: 15px;
  box-shadow: 0 20px 40px rgba(0,0,0,0.5);
  user-select: none;
}
.comparison-slider img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  pointer-events: none;
}
.comparison-overlay {
  position: absolute;
  top: 0; left: 0;
  width: 50%;
  height: 100%;
  overflow: hidden;
}
.comparison-overlay img {
  width: 800px;
  height: 100%;
}
.comparison-handle {
  position: absolute;
  top: 0;
  left: 50%;
  width: 40px;
  height: 100%;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  cursor: ew-resize;
  z-index: 10;
}
.handle-line {
  position: absolute;
  top: 0; bottom: 0;
  width: 4px;
  background-color: white;
  box-shadow: 0 0 10px rgba(0,0,0,0.5);
}
.handle-button {
  position: relative;
  width: 50px;
  height: 50px;
  background-color: white;
  border-radius: 50%;
  display: flex;
  justify-content: center;
  align-items: center;
  box-shadow: 0 0 15px rgba(0,0,0,0.5);
  color: #333;
  gap: -5px;
}
.handle-button svg { width: 18px; height: 18px; }
@media (max-width: 800px) {
  .comparison-slider { height: 350px; border-radius: 0; }
  .comparison-overlay img { width: 100vw; }
}

JavaScript Logic

document.addEventListener('DOMContentLoaded', () => {
    const slider = document.querySelector('.comparison-slider');
    const overlay = document.getElementById('overlay');
    const handle = document.getElementById('handle');
    if(!slider || !overlay || !handle) return;

    let isDragging = false;

    slider.addEventListener('mousedown', (e) => { isDragging = true; updateSlider(e); });
    window.addEventListener('mouseup', () => { isDragging = false; });
    window.addEventListener('mousemove', (e) => { if (isDragging) updateSlider(e); });

    slider.addEventListener('touchstart', (e) => { isDragging = true; updateSlider(e.touches[0]); });
    window.addEventListener('touchend', () => { isDragging = false; });
    window.addEventListener('touchmove', (e) => { if (isDragging) updateSlider(e.touches[0]); });

    function updateSlider(e) {
        const sliderRect = slider.getBoundingClientRect();
        let x = e.clientX - sliderRect.left;
        
        if (x < 0) x = 0;
        if (x > sliderRect.width) x = sliderRect.width;

        overlay.style.width = `${x}px`;
        handle.style.left = `${x}px`;
    }
});