12+ JavaScript Comparison Slider Examples

This post contains a total of 12+ Hand-Picked JavaScript Comparison Slider Examples with Source Code. All these Comparison Sliders are made using JavaScript and Styled using CSS.

You can use the source code of these examples with credits to the original owner.

Related Posts

JavaScript Comparison Slider Examples

1. By Solygambas

Made by Solygambas. Image Comparison Slider. Source

<!DOCTYPE html>
<html lang="en" >
<head>
  <meta charset="UTF-8">
  <title></title>
<style>
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  background-color: #fef9f2;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100vh;
  overflow: hidden;
}

.container {
  position: relative;
  width: 60vw;
  height: 80vh;
}

.img-container-before,
.img-container-after {
  position: absolute;
  width: 60vw;
  height: 80vh;
}

.img-container-before {
  width: 30vw;
  overflow: hidden;
}

img {
  width: 60vw;
  height: 80vh;
  object-fit: cover;
}

.slider {
  width: 0.5rem;
  background: white;
  height: 100%;
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  z-index: 10;
  pointer-events: none;
}
</style>
</head>
<body>
  <div class="container">
      <div class="img-container-after">
        <img
          src="https://images.unsplash.com/photo-1605405748429-cc26b762fa16?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=1336&q=80"
          alt=""
          class="after"
        />
      </div>
      <div class="img-container-before">
        <img
          src="https://images.unsplash.com/photo-1605405747924-2709f6783d0a?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=1336&q=80"
          alt=""
          class="before"
        />
      </div>
      <div class="slider"></div>
    </div>
      <script>
const container = document.querySelector(".container");
const slider = document.querySelector(".slider");
const before = document.querySelector(".img-container-before");
const after = document.querySelector(".img-container-after");

const dragSlider = e => {
  let x = e.type.includes("mouse") ? e.layerX : e.touches[0].clientX;
  let size = container.offsetWidth;
  before.style.width = x + "px";
  slider.style.left = x + "px";
  if (x < 30) {
    before.style.width = 0;
    slider.style.left = 0;
  }
  if (x + 30 > size) {
    before.style.width = size + "px";
    slider.style.left = size + "px";
  }
};

// Mouse event
container.addEventListener("mousemove", dragSlider);
// Touch and drag events
container.addEventListener("touchstart", dragSlider);
container.addEventListener("touchmove", dragSlider);
    </script>
</body>
</html>

2. By PBM

Made by PBM. Car Image Slider. Source

<!DOCTYPE html>
<html lang="en" >
<head>
  <meta charset="UTF-8">
  <title></title>
<style>
body{
  background-color: #eee;
}

div{
  width: 600px;
  height: 400px;
  background: url(https://koenromers.com/cocoen/after.jpg);
  background-size: cover;
  position: relative;
  margin:30px auto;
  z-index:1;
}

div:after{
  content:'';
  position: absolute;
  width:0;
  height:0;
  border: 10px solid transparent;
  border-right: 10px solid white;
  left: 42%;
  top:50%;
  transform: translate(-50%, -50%);
  animation: left 1s 2 forwards alternate;
  opacity: .7;
}

div:before{
  content:'';
  position: absolute;
  width:0;
  height:0;
  border: 10px solid transparent;
  border-left: 10px solid white;
  left:58%;
  top:50%;
  transform: translate(-50%, -50%);
  z-index:10;
  animation: right 1s 2 forwards alternate;
  opacity: .7;
}

figure{
  position: absolute;
  background: url(https://koenromers.com/cocoen/before.jpg);
  background-size:cover;
  width: 50%;
  height:100%;
  margin:0;
  z-index: -1;
}

input[type=range]{
  -webkit-appearance: none;
  postion: absolute;
  width:100%;
  height:100%;
  background: black;
  opacity: .7;
  outline:none;
  margin:auto;
  padding:0;
}

input[type=range]::-webkit-slider-thumb {
  -webkit-appearance: none;
  height: 100%;
  width: 10px;
  background: white;
  position: relative;
  border:none;
  cursor: pointer;
  outline: 5px solid transparent;
  opacity:.7;
}

input[type=range]::-webkit-slider-runnable-track {
  width: 100%;
  height: 400px;
  background: transparent;
}

input[type=range]::-moz-range-thumb {
  height: 100%;
  width: 10px;
  background-color: white;
  position: relative;
  border:none;
  cursor: pointer;
  border-radius: 0;
  opacity:.7;
}

input[type=range]::-moz-range-track {
  width: 100%;
  height: 400px;
  background: transparent;
}

input[type=range]::-ms-thumb {
  height: 400px;
  width: 10px;
  background: white;
  position: relative;
  border:none;
  border-radius: 0;
  opacity:.7;
}

input[type=range]:focus::-ms-thumb {
  border: none;
}

input[type=range]::-ms-track {
  width: 100%;
  height: 400px;
  cursor: pointer;
  background: transparent;
  border-color: transparent;
  color: transparent;
}

input[type=range]::-ms-fill-lower, input[type=range]::-ms-fill-upper {
  background: transparent;
}

input[type=range]::-ms-tooltip{
  display:none;
}

@keyframes left{
  to{
    left: 40%;
  }
}

@keyframes right{
  to{
    left: 60%;
  }
}

@media(max-width: 620px){
  div{
    width:90%;
    height: 300px;
  }
  input[type=range]::-webkit-slider-runnable-track {
    height: 300px;
  }
  input[type=range]::-moz-range-track{
    height:300px;
  }
  input[type=range]::-ms-track{
    height:300px;
  }
  input[type=range]::-ms-thumb{
    height:300px;
  }
}
</style>
</head>
<body>
  <div>
  <figure>
  </figure>
  <input type="range" min=0 max=100 value=50/>
</div>
      <script>
document.querySelector("figure").style.width = this.value + "%";

setTimeout(hideTutorialElements, 1000);

document.querySelector("input").oninput = function () {
  compare(this);
};

//for IE
document.querySelector("input").onchange = function () {
  compare(this);
};

function compare(element) {
  if (element.value > 98) element.value = 98;else
  if (element.value < 2) element.value = 2;
  document.querySelector("figure").style.width = element.value + "%";
}

function hideTutorialElements() {
  document.querySelector("input[type=range]").style.background = "transparent";
  document.querySelector("input[type=range]").style.opacity = 1;
  //CSS pseudo-elements
  document.styleSheets[0].
  insertRule('div:after {display: none; }', 1);
  document.styleSheets[0].
  insertRule('div:before {display: none; }', 1);
}
    </script>
</body>
</html>
 

3. By Kocsten

Made by Kocsten. Before / After Image Comparison Slider. Source

<!DOCTYPE html>
<html lang="en" >
<head>
  <meta charset="UTF-8">
  <title></title>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/modernizr/2.8.3/modernizr.min.js" type="text/javascript"></script>
  <link href='https://fonts.googleapis.com/css?family=Open+Sans:400,300,700' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css">
<style>
*, *:after, *:before {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}

body {
  font-size: 100%;
  font-family: "Open Sans", sans-serif;
  color: #445b7c;
  background-color: #445b7c;
}

a {
  color: #dc717d;
  text-decoration: none;
}

img {
  max-width: 100%;
}

header {
  position: relative;
  height: 160px;
  line-height: 160px;
  text-align: center;
}
header h1 {
  font-size: 22px;
  font-size: 1.375rem;
  color: #ffffff;
  font-weight: 300;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
@media only screen and (min-width: 768px) {
  header {
    height: 240px;
    line-height: 240px;
  }
  header h1 {
    font-size: 32px;
    font-size: 2rem;
  }
}

.image-container {
  position: relative;
  width: 90%;
  max-width: 768px;
  margin: 2em auto;
}
.image-container img {
  display: block;
}
@media only screen and (min-width: 768px) {
  .image-container {
    margin: 4em auto;
  }
}

.image-label {
  position: absolute;
  bottom: 0;
  right: 0;
  color: #ffffff;
  padding: 1em;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  opacity: 0;
  -webkit-transform: translateY(20px);
  -moz-transform: translateY(20px);
  -ms-transform: translateY(20px);
  -o-transform: translateY(20px);
  transform: translateY(20px);
  -webkit-transition: -webkit-transform 0.3s 0.7s, opacity 0.3s 0.7s;
  -moz-transition: -moz-transform 0.3s 0.7s, opacity 0.3s 0.7s;
  transition: transform 0.3s 0.7s, opacity 0.3s 0.7s;
}
.image-label.is-hidden {
  visibility: hidden;
}
.is-visible .image-label {
  opacity: 1;
  -webkit-transform: translateY(0);
  -moz-transform: translateY(0);
  -ms-transform: translateY(0);
  -o-transform: translateY(0);
  transform: translateY(0);
}

.resize-image {
  position: absolute;
  top: 0;
  left: 0;
  width: 0;
  height: 100%;
  overflow: hidden;
  background: url("https://webdevtrick.com/wp-content/uploads/skynaturemod.jpg") no-repeat left top;
  background-size: auto 100%;
  -webkit-transform: translateZ(0);
  -moz-transform: translateZ(0);
  -ms-transform: translateZ(0);
  -o-transform: translateZ(0);
  transform: translateZ(0);
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
}
.resize-image .image-label {
  right: auto;
  left: 0;
}
.is-visible .resize-image {
  width: 50%;
  -webkit-animation: cd-bounce-in 0.7s;
  -moz-animation: cd-bounce-in 0.7s;
  animation: cd-bounce-in 0.7s;
}

@-webkit-keyframes cd-bounce-in {
  0% {
    width: 0;
  }
  60% {
    width: 55%;
  }
  100% {
    width: 50%;
  }
}
@-moz-keyframes cd-bounce-in {
  0% {
    width: 0;
  }
  60% {
    width: 55%;
  }
  100% {
    width: 50%;
  }
}
@keyframes cd-bounce-in {
  0% {
    width: 0;
  }
  60% {
    width: 55%;
  }
  100% {
    width: 50%;
  }
}
.handle {
  position: absolute;
  height: 44px;
  width: 44px;
  left: 50%;
  top: 50%;
  margin-left: -22px;
  margin-top: -22px;
  border-radius: 50%;
  background: #dc717d url("https://webdevtrick.com/wp-content/uploads/arrows.svg") no-repeat center center;
  cursor: move;
  box-shadow: 0 0 0 6px rgba(0, 0, 0, 0.2), 0 0 10px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.3);
  opacity: 0;
  -webkit-transform: translate3d(0, 0, 0) scale(0);
  -moz-transform: translate3d(0, 0, 0) scale(0);
  -ms-transform: translate3d(0, 0, 0) scale(0);
  -o-transform: translate3d(0, 0, 0) scale(0);
  transform: translate3d(0, 0, 0) scale(0);
}
.handle.draggable {
  background-color: #445b7c;
}
.is-visible .handle {
  opacity: 1;
  -webkit-transform: translate3d(0, 0, 0) scale(1);
  -moz-transform: translate3d(0, 0, 0) scale(1);
  -ms-transform: translate3d(0, 0, 0) scale(1);
  -o-transform: translate3d(0, 0, 0) scale(1);
  transform: translate3d(0, 0, 0) scale(1);
  -webkit-transition: -webkit-transform 0.3s 0.7s, opacity 0s 0.7s;
  -moz-transition: -moz-transform 0.3s 0.7s, opacity 0s 0.7s;
  transition: transform 0.3s 0.7s, opacity 0s 0.7s;
}
.codes{
  bottom: 5%;
  left: 5%;
  position: fixed;
}
.codes div {
  border: 2px solid black;
  font-size: 20px;
  padding: 10px;
  background-color: red;
}
.codes div a{
  text-decoration: none;
  color: white;
  font-weight: 800;
}
</style>
</head>
<body>
<figure class="image-container">
	<img src="https://webdevtrick.com/wp-content/uploads/skynature.jpg" alt="Original Image">
	<span class="image-label" data-type="original">Original</span>

	<div class="resize-image"> 
		<span class="image-label" data-type="modified">Modified</span>
	</div>

	<span class="handle"></span>
</figure> 
  <script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
      <script>
jQuery(document).ready(function ($) {
  //check if the .image-container is in the viewport 
  //if yes, animate it
  checkPosition($('.image-container'));
  $(window).on('scroll', function () {
    checkPosition($('.image-container'));
  });

  //make the .handle element draggable and modify .resize-image width according to its position
  drags($('.handle'), $('.resize-image'), $('.image-container'), $('.image-label[data-type="original"]'), $('.image-label[data-type="modified"]'));

  //upadate images label visibility
  $(window).on('resize', function () {
    updateLabel($('.image-label[data-type="modified"]'), $('.resize-image'), 'left');
    updateLabel($('.image-label[data-type="original"]'), $('.resize-image'), 'right');
  });
});

function checkPosition(container) {
  if ($(window).scrollTop() + $(window).height() * 0.5 > container.offset().top) {
    container.addClass('is-visible');
    //you can uncomment the following line if you don't have other events to bind to the window scroll
    // $(window).off('scroll');
  }
}

//draggable funtionality
function drags(dragElement, resizeElement, container, labelContainer, labelResizeElement) {
  dragElement.on("mousedown vmousedown", function (e) {
    dragElement.addClass('draggable');
    resizeElement.addClass('resizable');

    var dragWidth = dragElement.outerWidth(),
    xPosition = dragElement.offset().left + dragWidth - e.pageX,
    containerOffset = container.offset().left,
    containerWidth = container.outerWidth(),
    minLeft = containerOffset + 10,
    maxLeft = containerOffset + containerWidth - dragWidth - 10;

    dragElement.parents().on("mousemove vmousemove", function (e) {
      leftValue = e.pageX + xPosition - dragWidth;

      //constrain the draggable element to move inside his container
      if (leftValue < minLeft) {
        leftValue = minLeft;
      } else if (leftValue > maxLeft) {
        leftValue = maxLeft;
      }

      widthValue = (leftValue + dragWidth / 2 - containerOffset) * 100 / containerWidth + '%';

      $('.draggable').css('left', widthValue).on("mouseup vmouseup", function () {
        $(this).removeClass('draggable');
        resizeElement.removeClass('resizable');
      });

      $('.resizable').css('width', widthValue);

      updateLabel(labelResizeElement, resizeElement, 'left');
      updateLabel(labelContainer, resizeElement, 'right');

    }).on("mouseup vmouseup", function (e) {
      dragElement.removeClass('draggable');
      resizeElement.removeClass('resizable');
    });
    e.preventDefault();
  }).on("mouseup vmouseup", function (e) {
    dragElement.removeClass('draggable');
    resizeElement.removeClass('resizable');
  });
}

function updateLabel(label, resizeElement, position) {
  if (position == 'left') {
    label.offset().left + label.outerWidth() < resizeElement.offset().left + resizeElement.outerWidth() ? label.removeClass('is-hidden') : label.addClass('is-hidden');
  } else {
    label.offset().left > resizeElement.offset().left + resizeElement.outerWidth() ? label.removeClass('is-hidden') : label.addClass('is-hidden');
  }
}
    </script>
</body>
</html>
 

4. By FrankyJo

Made by FrankyJo. Image Comparison Slider with Grayscale Effect. Source

<!DOCTYPE html>
<html lang="en" >
<head>
  <meta charset="UTF-8">
  <title></title>
<style>
* {
    margin: 0;
    padding: 0;
}

body {
    display: flex;
    align-items: center;
    justify-content: center;
    background: #333333;
    height: 100vh;
}

.compare {
    position: relative;
    height: 400px;
    width: 700px;
    overflow: hidden;
}

.compare__delimeter {
    position: absolute;
    top: 0px;
    width: 3px;
    height: 100%;
    background: #333333;
    cursor: grab;
    z-index: 2;
}

.compare__delimeter:before, .compare__delimeter:after {
    content: '';
    display: block;
    position: absolute;
    top: 50%;
    width: 20px;
    height: 40px;
    background: #222222;
    border: 1px solid #f2f2f2;
    transform: translate(0, -50%);
}

.compare__delimeter:before {
    left: 5px;
    border-radius: 3px 20px 20px 3px;
}

.compare__delimeter:after {
    right: 5px;
    border-radius: 20px 3px 3px 20px;
}

.compare__image {
    position: absolute;
    width: 100%;
    height: 100%;
    overflow: hidden;
    border-radius: 5px;
}

.compare__image img {
    width: 700px;
    height: 400px;
    object-fit: cover;
}

.compare__after {
    filter: grayscale(1);
}
</style>
</head>
<body>
  <div class="compare">
  <div class="compare__image">
    <img src="https://wallpaperaccess.com/full/1131217.jpg" alt="">
  </div>
  <div class="compare__delimeter"></div>
  <div class="compare__image compare__after" >
    <img src="https://wallpaperaccess.com/full/1131217.jpg" alt="">
  </div>
</div>
      <script>
const imageAfter = document.querySelector('.compare__after');
const widthImageAfter = imageAfter.offsetWidth;
const heightImageAfter = imageAfter.offsetHeight;
const delimeter = document.querySelector('.compare__delimeter');
let isActive = false;

compare();

function compare() {
  delimeter.style.left = widthImageAfter / 2 - delimeter.offsetWidth / 2 + 'px';
  imageAfter.style.width = '50%';

  setListeners();
}

function setListeners() {
  delimeter.addEventListener('mousedown', activeDelimeter);
  delimeter.addEventListener('touchstart', activeDelimeter);

  window.addEventListener('mousemove', onMoveDelimeter);
  window.addEventListener('touchmove', onMoveDelimeter);


  window.addEventListener('mouseup', () => {
    isActive = false;
  });
  window.addEventListener('touchstop', () => {
    isActive = false;
  });
}


function activeDelimeter(event) {
  event.preventDefault();

  isActive = true;
}

function onMoveDelimeter(event) {
  if (!isActive) return;

  moveSlide(currentPositionDelimeter(event));
}

function currentPositionDelimeter(event) {
  let image = imageAfter.getBoundingClientRect();
  let x = 0;
  x = event.pageX - image.left;

  if (x < 0) {
    x = 0;
  }

  if (x > widthImageAfter) {
    x = widthImageAfter;
  }

  return x;
}


function moveSlide(x) {
  imageAfter.style.width = x + 'px';

  delimeter.style.left = imageAfter.offsetWidth - delimeter.offsetWidth / 2 + 'px';

}
    </script>
</body>
</html>

5. By Cam

Made by Cam. JavaScript Image Comparison slider with automatic cursor follower. Source

<!DOCTYPE html>
<html lang="en" >
<head>
  <meta charset="UTF-8">
  <title></title>
<style>
body {
  background: radial-gradient(at 70% top, #fff 0%, #e0e0e0 100%);
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  width: 100%;
}

.Image-Compare {
  --width: 794px;
  --height: 446px;
  position: relative;
  width: var(--width);
  height: var(--height);
  overflow: hidden;
}
.Image-Compare__image {
  position: absolute;
  height: 100%;
  background: url("https://images.unsplash.com/photo-1498248193836-88f8c8d70a3f?w=2382&ixid=dW5zcGxhc2guY29tOzs7Ozs%3D");
  background-size: var(--width) var(--height);
}
.Image-Compare__image:first-child {
  left: 0;
  width: 100%;
  background-position: center left;
}
.Image-Compare__image:last-child {
  right: 0;
  width: calc(100% - var(--x, 50%));
  background-position: center right;
  filter: grayscale(100%);
  box-shadow: inset 2px 0 0 #111, -2px 0 0 #111;
}
</style>
</head>
<body>
  <div class="Contain">
  <div class="Image-Compare">
    <div class="Image-Compare__image"></div>
    <div class="Image-Compare__image"></div>
  </div>
</div>
      <script>
document.querySelectorAll('.Image-Compare').forEach(function (elem) {
  var x = undefined,
  width = undefined;
  elem.onmouseenter = function () {
    var size = elem.getBoundingClientRect();

    x = size.x;
    width = size.width;
  };

  elem.onmousemove = function (e) {
    var horizontal = (e.clientX - x) / width * 100;

    elem.style.setProperty('--x', horizontal + '%');
  };
});
    </script>
</body>
</html>

6. By Arthur

Made by Arthur. Before / After Comparison slider with range button. Source

<!DOCTYPE html>
<html lang="en" >
<head>
  <meta charset="UTF-8">
  <title></title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Oswald&display=swap" rel="stylesheet">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">

<style>
@charset "UTF-8";
/* ___ variables ___ */
/* 
__ mixins.scss __ 

*/
/* ___ global.scss */
*,
*::before,
*::after {
  box-sizing: inherit;
}

body {
  min-height: 100vh;
  display: grid;
  place-items: center;
  box-sizing: border-box;
  font-family: "Oswald", "Arial", "Helvetica", sans-serif;
  background-color: #eaeaea;
  text-transform: uppercase;
  grid-template-columns: min(100%, 300px);
  place-content: center;
  padding-left: 20px;
  padding-right: 20px;
}
@media (min-width: 600px) {
  body {
    --back-divide: 50%;
    background-image: linear-gradient(to right, transparent var(--back-divide), #dddddd var(--back-divide));
  }
}

/* 
__ visually-hidden.scss __ 
ДоступноС скрытиС
*/
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  border: 0;
  clip: rect(0 0 0 0);
}

/* __ switcher.scss __ */
.switcher {
  border: none;
  padding: 0;
  margin: 0;
  position: relative;
  display: grid;
  grid-template-columns: -webkit-min-content 1fr -webkit-min-content;
  grid-template-columns: min-content 1fr min-content;
  align-items: center;
  gap: 18px;
}
.switcher[hidden] {
  display: none;
}
.switcher__wrapper {
  background-color: #fff;
  display: inline-flex;
  border: 1px solid #cdcdcd;
  border-radius: 6px;
  min-width: 40px;
  height: 14px;
  cursor: pointer;
  position: relative;
}
.switcher__wrapper:hover, .switcher__wrapper:focus-within {
  border-color: #ff91ab;
  background-color: #f2f2f2;
}
.switcher__radio {
  display: inline-block;
  margin-right: -2px;
  width: 50%;
  height: 100%;
  opacity: 0;
  position: relative;
  z-index: 1;
  cursor: pointer;
}
.switcher__thumb {
  height: 42.86%;
  width: calc(50% - 6px);
  display: block;
  background-color: #ff91ab;
  border-radius: 6px;
  transition: transform 0.1s ease-out;
  z-index: 2;
  position: absolute;
  left: 6px;
  top: 28.57%;
  pointer-events: none;
}
.switcher__radio--on:checked ~ .switcher__thumb {
  transform: translateX(100%);
}

.comparison__slides {
  margin: 0 0 20px;
  padding: 0;
  list-style: none;
  overflow-x: auto;
  display: flex;
  -ms-scroll-snap-type: x mandatory;
      scroll-snap-type: x mandatory;
  scrollbar-color: transparent transparent;
  /* thumb and track color */
  scrollbar-width: 0px;
  -ms-overflow-style: none;
}
.comparison__slides::-webkit-scrollbar {
  width: 0;
  height: 0;
}
.comparison__slides::-webkit-scrollbar-track {
  background: transparent;
}
.comparison__slides::-webkit-scrollbar-thumb {
  background: transparent;
  border: none;
}
.comparison__slide {
  flex: 0 0 100%;
  display: block;
  scroll-snap-align: start;
}
.comparison__image {
  width: 100%;
  height: auto;
}
.comparison__controls {
  display: grid;
  gap: 12px;
}
.comparison__range-wrapper {
  display: grid;
  gap: 22px;
  grid-auto-flow: column;
  align-items: center;
  padding: 0;
  margin: 0;
  border: none;
}
.comparison__range-wrapper--activated {
  grid-template-columns: -webkit-min-content 1fr -webkit-min-content;
  grid-template-columns: min-content 1fr min-content;
  display: none;
}
.comparison__control {
  color: inherit;
  font-size: 16px;
  line-height: 1.25;
  text-transform: uppercase;
  color: #000000;
}
.comparison__control[href] {
  -webkit-text-decoration: underline dotted rgba(0, 0, 0, 0.24);
          text-decoration: underline dotted rgba(0, 0, 0, 0.24);
  text-underline-offset: 0.2em;
}
.comparison__control--right {
  text-align: right;
}
@media (min-width: 600px) {
  .comparison__range-wrapper--activated {
    display: grid;
  }
  .comparison__switcher {
    display: none;
  }
  .comparison__slides {
    position: relative;
    width: 100%;
    --slider-divide: 50%;
  }
  .comparison__slide {
    -webkit-clip-path: polygon(0 0, var(--slider-divide) 0, var(--slider-divide) 100%, 0 100%);
            clip-path: polygon(0 0, var(--slider-divide) 0, var(--slider-divide) 100%, 0 100%);
  }
  .comparison__slide:last-child {
    position: absolute;
    width: 100%;
    height: 100%;
    -webkit-clip-path: polygon(var(--slider-divide) 0, 100% 0, 100% 100%, var(--slider-divide) 100%);
            clip-path: polygon(var(--slider-divide) 0, 100% 0, 100% 100%, var(--slider-divide) 100%);
  }
}

.custom-range[type=range] {
  width: 100%;
  margin: 15px 0;
  background-color: transparent;
  -webkit-appearance: none;
}
.custom-range[type=range]:focus {
  outline: none;
}
.custom-range[type=range]:hover::-webkit-slider-thumb {
  box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.2), inset 0px 0 0px 10px white;
}
.custom-range[type=range]:focus::-webkit-slider-thumb, .custom-range[type=range]:active::-webkit-slider-thumb {
  box-shadow: 0px 3px 5px rgba(0, 0, 0, 0.2), inset 0px 0 0px 10px white;
  border-color: #ff91ab;
}
.custom-range[type=range]::-webkit-slider-runnable-track {
  background-color: #c4c4c4;
  border-radius: 6px;
  width: 100%;
  height: 6px;
  cursor: pointer;
}
.custom-range[type=range]::-moz-range-track {
  background-color: #c4c4c4;
  border-radius: 6px;
  width: 100%;
  height: 6px;
  cursor: pointer;
}
.custom-range[type=range]::-webkit-slider-thumb {
  margin-top: -12px;
  width: 30px;
  height: 30px;
  background-color: #ff91ab;
  border: 1px solid #cdcdcd;
  border-radius: 50%;
  cursor: pointer;
  box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.16), inset 0px 0 0px 10px white;
  -webkit-appearance: none;
}
.custom-range[type=range]::-moz-range-thumb {
  width: 30px;
  height: 30px;
  background-color: #ff91ab;
  border: 1px solid #cdcdcd;
  border-radius: 50%;
  cursor: pointer;
  box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.16), inset 0px 0 0px 10px white;
}
</style>
</head>
<body>
  <article class="comparison">
  <ul class="comparison__slides">
    <li class="comparison__slide" id="before"><img class="comparison__image" src="https://svgur.com/i/WRr.svg" width="224" height="224" alt="Kitty wants coffee"/></li>
    <li class="comparison__slide" id="after"><img class="comparison__image" src="https://svgur.com/i/WQf.svg" width="224" height="224" alt="Kitty is ready"/></li>
  </ul>
  <form class="comparison__controls">
    <fieldset class="comparison__range-wrapper">
      <legend class="visually-hidden">Choose which picture to show</legend><a class="comparison__control" href="#before">Before</a>
      <input class="comparison__range custom-range" type="range" min="0" max="100" value="50" hidden="hidden"/><a class="comparison__control comparison__control--right" href="#after">After</a>
    </fieldset>
    <fieldset class="switcher comparison__switcher" role="radiogroup" hidden="hidden">
      <legend class="visually-hidden">Comparison switcher</legend>
      <label class="comparison__control" for="before-radio">Before</label>
      <div class="switcher__wrapper">
        <input class="switcher__radio" id="before-radio" type="radio" name="comparison-switcher" checked="checked"/>
        <input class="switcher__radio switcher__radio--on" id="after-radio" type="radio" name="comparison-switcher"/><span class="switcher__thumb" aria-hidden="true"></span>
      </div>
      <label class="comparison__control" for="after-radio">After</label>
    </fieldset>
  </form>
</article>
      <script>
/* switcher.js */
const switcher = document.querySelector(".switcher");
const switcherWrapper = switcher.querySelector(".switcher__wrapper");
const switcherRadios = switcherWrapper.querySelectorAll(".switcher__radio");

switcherWrapper.addEventListener("focusin", evt => {
  switcherWrapper.addEventListener("keydown", evt => {
    if (event.key === "Enter" || event.key === " ") {
      evt.preventDefault();
      toogleSwitch();
    }
  });
});

function toogleSwitch() {
  if (switcherRadios[0].checked) {
    switcherRadios[1].checked = true;
  } else {
    switcherRadios[0].checked = true;
  }
}

/* comparison.js */

const compasion = document.querySelector(".comparison");
const compasionWrapper = compasion.querySelector(".comparison__slides");
const WIDTH = compasionWrapper.offsetWidth;
const compasionSlides = compasionWrapper.querySelectorAll(".comparison__slide");
const compasionRange = compasion.querySelector(".comparison__range");

const compasionSwitcher = compasion.querySelector(".comparison__switcher");
const compasionRadios = compasionSwitcher.querySelectorAll(".switcher__radio");
const compasionControls = compasion.querySelectorAll("a.comparison__control");

compasionSwitcher.hidden = false;
compasionRange.hidden = false;
compasionRange.parentElement.classList.add(
`${compasionRange.parentElement.classList[0]}--activated`);


compasionSwitcher.addEventListener("change", evt => {
  const scrollPosition = evt.target.id.includes("after") ? WIDTH : 0;

  compasionWrapper.scrollTo({
    left: scrollPosition,
    behavior: "smooth" });

});

compasionRange.addEventListener("input", updateSlider);

compasionControls.forEach((control, index) => {
  control.addEventListener("click", evt => {
    evt.preventDefault();
    compasionRange.value =
    index === 0 ? compasionRange.min : compasionRange.max;
    updateSlider();
  });
});

function updateSlider() {
  const inverseValue = compasionRange.max - compasionRange.value;

  compasionWrapper.style.setProperty("--slider-divide", inverseValue + "%");

  const parentWidth = compasion.parentNode.offsetWidth;
  let backgroundDividePoint =
  compasionWrapper.offsetLeft + WIDTH * inverseValue / compasionRange.max;

  updateBackround(backgroundDividePoint + "px");

  if (compasionRange.value === compasionRange.max) {
    updateBackround(0);
  }

  if (compasionRange.value === compasionRange.min) {
    updateBackround("100%");
  }
}

function updateBackround(value) {
  compasion.parentNode.style.setProperty("--back-divide", value);
}
    </script>
</body>
</html>

7. By Ivan Markovic

Made by Ivan Markovic. Responsive image comparison slider. Source

<!DOCTYPE html>
<html lang="en" >
<head>
  <meta charset="UTF-8">
  <title></title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
<style>
* {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

.container {
    position: relative;
    width: 100%;
    height: 100vh;
    background-image: url(https://raw.githubusercontent.com/ivanmmarkovic/misc/master/images/large/aerial-shot-bird-s-eye-view-forest-1660004.jpg);
    background-position: center center;
    background-size: cover;
    overflow: hidden;
}

.mask-container {
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    width: 50%;
    overflow: hidden;
}

.mask-image-container {
    position: absolute;
    top: 0;
    left: 0;
    height: 100vh;
    width: 100vw;
    background-image: url(https://raw.githubusercontent.com/ivanmmarkovic/misc/master/images/large/aerial-view-color-daylight-1125278.jpg);
    background-position: center center;
    background-size: cover;
}

.border {
    position: absolute;
    width: 4px;
    height: 100vh;
    left: 50%;
    margin-left: -2px;
    background-color: rgba(0,0,0,0.4);
}

.circle {
    position: absolute;
    width: 50px;
    height: 50px;
    border-radius: 50%;
    background-color: steelblue;
    top: 50%;
    margin-top: -25px;
    left: 50%;
    margin-left: -25px;
    opacity: 0.9;
    cursor: ew-resize;
}
</style>
</head>
<body>
  <div class="container">

        <div class="mask-container">

            <div class="mask-image-container">
            </div>

        </div>

        <div class="border"></div>
        <div class="circle"></div>
    </div>
      <script>
let container = document.querySelector(".container");
let maskContainer = document.querySelector(".mask-container");
let maskImageContainer = document.querySelector(".mask-image-container");

let border = document.querySelector(".border");
let circle = document.querySelector(".circle");

circle.style.draggable = true;

circle.ondrag = function (event) {
  maskContainer.style.width = event.pageX + "px";
  border.style.left = event.pageX + "px";
  circle.style.left = event.pageX + "px";
};

circle.ondragend = function (event) {
  maskContainer.style.width = event.pageX + "px";
  border.style.left = event.pageX + "px";
  circle.style.left = event.pageX + "px";
};
    </script>
</body>
</html>

8. By boomclap

Made by boomclap. Basic JavaScript Photo Comparison Slider. Source

<!DOCTYPE html>
<html lang="en" >
<head>
  <meta charset="UTF-8">
  <title></title>
  <link href='https://fonts.googleapis.com/css?family=Open+Sans:400,300,700' rel='stylesheet' type='text/css'>
<style>
.cd-image-container {
  position: relative;
  width: 90%;
  max-width: 1080px;
  margin: 0em auto;
  }
.cd-image-container img {
  display: block;
}

.cd-image-label {
  position: absolute;
  bottom: 0;
  right: 55px;
  color: #000000;
  padding: 1em;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  opacity: 0;
  -webkit-transform: translateY(20px);
  -moz-transform: translateY(20px);
  -ms-transform: translateY(20px);
  -o-transform: translateY(20px);
  transform: translateY(20px);
  -webkit-transition: -webkit-transform 0.3s 0.7s, opacity 0.3s 0.7s;
  -moz-transition: -moz-transform 0.3s 0.7s, opacity 0.3s 0.7s;
  transition: transform 0.3s 0.7s, opacity 0.3s 0.7s;
}
.cd-image-label.is-hidden {
  visibility: hidden;
}
.is-visible .cd-image-label {
  opacity: 1;
  -webkit-transform: translateY(0);
  -moz-transform: translateY(0);
  -ms-transform: translateY(0);
  -o-transform: translateY(0);
  transform: translateY(0);
}

.cd-resize-img {
  position: absolute;
  top: 0;
  left: 0;
  width: 0;
  height: 100%;
  overflow: hidden;
  /* Force Hardware Acceleration in WebKit */
  -webkit-transform: translateZ(0);
  -moz-transform: translateZ(0);
  -ms-transform: translateZ(0);
  -o-transform: translateZ(0);
  transform: translateZ(0);
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
}
.cd-resize-img img {
  position: absolute;
  left: 0;
  top: 0;
  display: block;
  height: 100%;
  width: auto;
  max-width: none;
}
.cd-resize-img .cd-image-label {
  right: auto;
  left: 0;
}
.is-visible .cd-resize-img {
  width: 50%;
  /* bounce in animation of the modified image */
  -webkit-animation: cd-bounce-in 0.7s;
  -moz-animation: cd-bounce-in 0.7s;
  animation: cd-bounce-in 0.7s;
}

@-webkit-keyframes cd-bounce-in {
  0% {
    width: 0;
  }
  60% {
    width: 55%;
  }
  100% {
    width: 50%;
  }
}
@-moz-keyframes cd-bounce-in {
  0% {
    width: 0;
  }
  60% {
    width: 55%;
  }
  100% {
    width: 50%;
  }
}
@keyframes cd-bounce-in {
  0% {
    width: 0;
  }
  60% {
    width: 55%;
  }
  100% {
    width: 50%;
  }
}
.cd-handle {
  position: absolute;
  height: 44px;
  width: 44px;
  /* center the element */
  left: 50%;
  top: 50%;
  margin-left: -22px;
  margin-top: -22px;
  border-radius: 50%;
  background: #dc717d url("https://codyhouse.co/demo/image-comparison-slider/img/cd-arrows.svg") no-repeat center center;
  cursor: move;
  box-shadow: 0 0 0 6px rgba(0, 0, 0, 0.2), 0 0 10px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.3);
  opacity: 0;
  -webkit-transform: translate3d(0, 0, 0) scale(0);
  -moz-transform: translate3d(0, 0, 0) scale(0);
  -ms-transform: translate3d(0, 0, 0) scale(0);
  -o-transform: translate3d(0, 0, 0) scale(0);
  transform: translate3d(0, 0, 0) scale(0);
}
.cd-handle.draggable {
  /* change background color when element is active */
  background-color: #445b7c;
}
.is-visible .cd-handle {
  opacity: 1;
  -webkit-transform: translate3d(0, 0, 0) scale(1);
  -moz-transform: translate3d(0, 0, 0) scale(1);
  -ms-transform: translate3d(0, 0, 0) scale(1);
  -o-transform: translate3d(0, 0, 0) scale(1);
  transform: translate3d(0, 0, 0) scale(1);
  -webkit-transition: -webkit-transform 0.3s 0.7s, opacity 0s 0.7s;
  -moz-transition: -moz-transform 0.3s 0.7s, opacity 0s 0.7s;
  transition: transform 0.3s 0.7s, opacity 0s 0.7s;
}
</style>
</head>
<body>
	<figure class="cd-image-container">
		<img src="http://gearnuke.com/wp-content/uploads/2015/04/gtav-ps4-comp-3-1024x576.jpg" style="max-width: 100%;"alt="Original Image" >
		<span class="cd-image-label" data-type="original">Text</span>

		<div class="cd-resize-img slide-img" > <!-- the resizable image on top -->
			<img src="http://gearnuke.com/wp-content/uploads/2015/04/gtav-pc-normal-9-1024x576.jpg" alt="Modified Image" >
			<span class="cd-image-label" data-type="modified">Text</span>
		</div>
		<span class="cd-handle"></span>
	</figure> <!-- cd-image-container -->
  <script src='https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.js'></script>
<script src='https://code.jquery.com/jquery-2.1.1.js'></script>
      <script>
jQuery(document).ready(function ($) {
  //check if the .cd-image-container is in the viewport 
  //if yes, animate it
  checkPosition($('.cd-image-container'));
  $(window).on('scroll', function () {
    checkPosition($('.cd-image-container'));
  });

  //make the .cd-handle element draggable and modify .cd-resize-img width according to its position
  $('.cd-image-container').each(function () {
    var actual = $(this);
    drags(actual.find('.cd-handle'), actual.find('.cd-resize-img'), actual, actual.find('.cd-image-label[data-type="original"]'), actual.find('.cd-image-label[data-type="modified"]'));
  });

  //upadate images label visibility
  $(window).on('resize', function () {
    $('.cd-image-container').each(function () {
      var actual = $(this);
      updateLabel(actual.find('.cd-image-label[data-type="modified"]'), actual.find('.cd-resize-img'), 'left');
      updateLabel(actual.find('.cd-image-label[data-type="original"]'), actual.find('.cd-resize-img'), 'right');
    });
  });
});

function checkPosition(container) {
  container.each(function () {
    var actualContainer = $(this);
    if ($(window).scrollTop() + $(window).height() * 0.5 > actualContainer.offset().top) {
      actualContainer.addClass('is-visible');
    }
  });
}

//draggable funtionality - credits to https://css-tricks.com/snippets/jquery/draggable-without-jquery-ui/
function drags(dragElement, resizeElement, container, labelContainer, labelResizeElement) {
  dragElement.on("mousedown vmousedown", function (e) {
    dragElement.addClass('draggable');
    resizeElement.addClass('resizable');

    var dragWidth = dragElement.outerWidth(),
    xPosition = dragElement.offset().left + dragWidth - e.pageX,
    containerOffset = container.offset().left,
    containerWidth = container.outerWidth(),
    minLeft = containerOffset + 10,
    maxLeft = containerOffset + containerWidth - dragWidth - 10;

    dragElement.parents().on("mousemove vmousemove", function (e) {
      leftValue = e.pageX + xPosition - dragWidth;

      //constrain the draggable element to move inside his container
      if (leftValue < minLeft) {
        leftValue = minLeft;
      } else if (leftValue > maxLeft) {
        leftValue = maxLeft;
      }

      widthValue = (leftValue + dragWidth / 2 - containerOffset) * 95 / containerWidth + '%';

      $('.draggable').css('left', widthValue).on("mouseup vmouseup", function () {
        $(this).removeClass('draggable');
        resizeElement.removeClass('resizable');
      });

      $('.resizable').css('width', widthValue);

      updateLabel(labelResizeElement, resizeElement, 'left');
      updateLabel(labelContainer, resizeElement, 'right');

    }).on("mouseup vmouseup", function (e) {
      dragElement.removeClass('draggable');
      resizeElement.removeClass('resizable');
    });
    e.preventDefault();
  }).on("mouseup vmouseup", function (e) {
    dragElement.removeClass('draggable');
    resizeElement.removeClass('resizable');
  });
}

function updateLabel(label, resizeElement, position) {
  if (position == 'left') {
    label.offset().left + label.outerWidth() < resizeElement.offset().left + resizeElement.outerWidth() ? label.removeClass('is-hidden') : label.addClass('is-hidden');
  } else {
    label.offset().left > resizeElement.offset().left + resizeElement.outerWidth() ? label.removeClass('is-hidden') : label.addClass('is-hidden');
  }
}
    </script>
</body>
</html>

9. By Nahid

Made by Nahid. Image Comparison Slider with Grayscale effect. Source

<!DOCTYPE html>
<html lang="en" >
<head>
  <meta charset="UTF-8">
  <title></title>
<style>
* {
    padding: 0;
    margin: 0;
    /* box-sizing: border-box; */
    /* cursor: none !important; */
    font-family: 'Poppins', sans-serif;
}

section {
    position: absolute;
    width: 100%;
    height: 100vh;
    overflow: hidden;
    background: url(https://images.hdqwalls.com/wallpapers/urban-cityscape-artwork-cq.jpg);
    background-position: center;
    background-size: cover;
    background-attachment: fixed;
}

#layer {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100vh;
    background: url(https://images.hdqwalls.com/wallpapers/urban-cityscape-artwork-cq.jpg);
    background-position: center;
    background-size: cover;
    filter: grayscale(100%);
    background-attachment: fixed;
    border-left: 5px solid #fff;
}
</style>
</head>
<body>
  <section>
        <div id="layer"></div>
    </section>
      <script>
var slide = document.getElementById("layer");
window.onmousemove = function (e) {
  var x = e.clientX;
  slide.style.left = x + "px";
  // var y = e.clientY
};
    </script>
</body>
</html>

10. By Qrolic Technologies

Made by Qrolic Technologies. Image before & after comparison slider using JQuery. Source

<!DOCTYPE html>
<html lang="en" >
<head>
  <meta charset="UTF-8">
  <title></title>
  <link rel='stylesheet' href='https://cdn.jsdelivr.net/foundation/5.5.0/css/foundation.css'>
<link rel='stylesheet' href='https://s3-us-west-2.amazonaws.com/s.cdpn.io/124874/twentytwenty.css'>
<style>
@import url('https://fonts.googleapis.com/css2?family=Poppins:[email protected];200;300;400;500;600;700;800&display=swap');

body{
  font-family: 'Poppins', sans-serif;
  background-color: #EDF2F4;
}

.container{
  width: 100%;
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
}
.box__inner{
  width: 600px;
}
.title span{
  color: #EF233C;
}
.title{
  padding-bottom: 50px;
  text-align: center;
}
p{
  color: #2B2D42;
  font-size: 20px;
  line-height: 25px;
}
a{
  color: #EF233C;
}
a:hover{
  color: #8D99AE;
}
h1 {
  text-align: center;
  font-size: 35px;
  line-height: 40px;
  color: #2B2D42;
  font-weight: 600;
  font-family: 'Poppins', sans-serif;
}
</style>
</head>
<body>
  <section>
  <div class="container">
    <div class="content">
      <div class="title">
      <div class="box">
        <div class="box__inner">
          <div id="before_after">
            <img src="https://i.ibb.co/F8rDyhv/before.jpg">
          <img src="https://i.ibb.co/0shfDNN/after.jpg">
          </div>
        </div>
      </div>
    </div>
  </div>
</section>
  <script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
<script src='https://s3-us-west-2.amazonaws.com/s.cdpn.io/124874/jquery.event.move.js'></script>
<script src='https://s3-us-west-2.amazonaws.com/s.cdpn.io/124874/jquery.twentytwenty.js'></script>
      <script>
$(window).load(function () {
  $("#before_after").twentytwenty();
});
    </script>
</body>
</html>

11. By Mcli

Made by Mcli. Basic JavaScript image comparison slider with Random images on reload. Source

<!DOCTYPE html>
<html lang="en" >
<head>
  <meta charset="UTF-8">
  <title></title>
<style>
body {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100vh;
}

.ComparisonSlider {
  position: relative;
  user-select: none;
}

.ComparisonSlider * {
  box-sizing: border-box;
}

.ComparisonSlider > div {
  position: absolute;
  height: 100%;
  width: 100%;
  z-index: 1;
  overflow: hidden;
}

.ComparisonSlider > div > img {
  position: relative;
  display: block;
  height: 100%;
  width: auto;
}

/* the slider */
.ComparisonSlider > span {
  position: absolute;
  top: 0;
  left: calc(50% - 30px);
  height: 100%;
  width: 60px;
  cursor: ew-resize;
  z-index: 3;
  
}
</style>
</head>
<body>
  <body id="body">
</body>
      <script>
document.addEventListener('DOMContentLoaded', run);

function run() {

  const container = document.getElementById('body');
  const images = [
  "https://source.unsplash.com/random/700x500",
  "https://source.unsplash.com/random/800x600"];

  const dimensions = { width: 1000, height: 600 };

  new ComparisonSlider(container, images, dimensions);
}

//the container will be built with absolute pixel dimensions

class ComparisonSlider {
  constructor(node, images, dims) {
    //node = DOM parent node
    //images = array of image src paths
    //dims = object with width and height props
    this._node = node;
    this._width = validate(dims.width);
    this._height = validate(dims.height);
    this._container = null;
    this._div1 = null;
    this._div2 = null;
    this._img1 = null;
    this._img2 = null;
    this._small = null;
    this._slider = null;
    this._images = images;
    this.build(this.node);
    //helper
    function validate(prop) {
      if (Number(prop)) {
        return Number(prop);
      } else {
        return 500;
      }
    }
  }
  get node() {
    return this._node;
  }
  get images() {
    return this._images;
  }
  get container() {
    return this._container;
  }
  get width() {
    return this._width;
  }
  get height() {
    return this._height;
  }
  get div1() {
    return this._div1;
  }
  get div2() {
    return this._div2;
  }
  get img1() {
    return this._img1;
  }
  get img2() {
    return this._img2;
  }
  get small() {
    return this._small;
  }
  get slider() {
    return this._slider;
  }

  setSmall(node) {
    this._small = node;
    this._width = node.offsetWidth;
  }

  build(node) {
    let container = document.createElement('div');
    let div1 = document.createElement('div');
    let div2 = document.createElement('div');
    let img1 = document.createElement('img');
    let img2 = document.createElement('img');
    //container setup
    container.className = "ComparisonSlider";
    container.style.width = this.width + 'px';
    container.style.height = this.height + 'px';
    //hide everything until async load complete
    container.style.opacity = 0;
    //append
    div1.append(img1);
    div2.append(img2);
    container.append(div1);
    container.append(div2);
    node.append(container);
    //attach to object props
    this._container = container;
    this._div1 = div1;
    this._div2 = div1;
    this._img1 = img1;
    this._img2 = img2;
    //get image paths
    let path1 = this.images[0];
    let path2 = this.images[1];
    let setSmall = this.setSmall.bind(this);
    //counter to track when both images sized
    let loadCounter = 2;
    //when setDims are complete, run buildReady
    const buildReady = () => {
      //show when ready
      this.container.style.opacity = 1;
      //next script
      this.insertSlider();
    };
    //determine image widths via async
    setDims(img1, path1);
    setDims(img2, path2);
    //helper get and set dims of image elements
    function setDims(elem, url) {
      var img = new Image();
      img.onload = function () {
        elem.width = this.naturalWidth;
        elem.height = this.naturalHeight;
        elem.src = url;
        loadCounter--;
        //after both images dims load -- resize container to smaller width
        if (loadCounter < 1) {
          let w1 = img1.offsetWidth;
          let w2 = img2.offsetWidth;
          if (w1 < w2) {
            resize(w1, w2, img1, img2);
          } else {
            resize(w2, w1, img2, img1);
          }
          buildReady();
          //helper resize
          function resize(small, big, smallNode, bigNode) {
            container.style.width = small + 'px';
            let dif = big - small;
            let offset = dif / 2;
            bigNode.style.left = -1 * offset + 'px';
            setSmall(smallNode);
          }
        }
      };
      img.src = url;
    }
  }

  insertSlider() {
    //split and format images
    let smallDiv = this.small.parentNode;
    smallDiv.style.zIndex = 2;
    let w = this.small.offsetWidth;
    smallDiv.style.width = w / 2 + 'px';
    smallDiv.style.borderRight = "1px solid rgba(0,0,0,0.5)";
    //insert slider element
    let slider = document.createElement('span');
    this.container.append(slider);
    this._slider = slider;
    this.initializeSlider();
  }

  initializeSlider() {
    let slider = this.slider;
    let small = this.small.parentNode;
    let fullWidth = this.width;
    slider.onmousedown = e => {
      e = e || window.event;
      e.stopPropagation();
      e.preventDefault();
      //get cursor x position
      var cursor = e.clientX;
      //set window mouse events
      window.onmousemove = drag;
      window.onmouseup = close;
      function drag(e) {
        e = e || window.event;
        e.stopPropagation();
        e.preventDefault();
        let offset = e.clientX - cursor;
        cursor = e.clientX;
        //deltas -- displacement
        let sliderD = slider.offsetLeft + offset;
        let smallD = small.offsetWidth + offset;
        //new positions after limit check
        let sliderPos = limit(sliderD, -30); //-30 offset for UI
        let smallPos = limit(smallD, 0);
        //change styles for new position
        slider.style.left = sliderPos + 'px';
        small.style.width = smallPos + 'px';
        //helper to keep position within bounds
        function limit(val, off) {
          if (val < off) {
            return off;
          } else if (val > fullWidth + off) {
            return fullWidth + off;
          } else {
            return val;
          }
        }
      }
      function close() {
        window.onmousemove = null;
        window.onmouseup = null;
      }
    };

  }}
    </script>
</body>
</html>

12. By Dom Catch

Made by Dom Catch. JavaScript Responsive Comparison Slider. Source

<!DOCTYPE html>
<html lang="en" >
<head>
  <meta charset="UTF-8">
  <title></title>
<style>
.wrapper {
  max-width: 1200px;
  margin: 0 auto;
}

.fs-comparison-slider {
  position: relative;
  width: 100%;
  height: 0;
  padding-bottom: 56.25%;
}
.fs-comparison-slider__bar {
  width: 2px;
  height: 100%;
  position: absolute;
  left: 5%;
  z-index: 1;
  cursor: pointer;
  background: linear-gradient(180deg, white 0, white calc(50% - 2rem), rgba(255, 255, 255, 0) calc(50% - 2rem), rgba(255, 255, 255, 0) calc(50% + 2rem), white calc(50% + 2rem), white 100%);
}
.fs-comparison-slider__bar:after {
  content: "";
  width: 64px;
  height: 64px;
  background: transparent;
  position: absolute;
  border-radius: 50%;
  border: 2px solid white;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  backdrop-filter: blur(3px);
}
.fs-comparison-slider__control {
  width: 100%;
}
.fs-comparison-slider__control input {
  width: 100%;
  height: 100%;
  z-index: 1;
  position: absolute;
  -webkit-appearance: none;
  appearance: none;
  outline: none;
  pointer-events: auto !important;
  background: none;
}
.fs-comparison-slider__control input::-webkit-slider-runnable-track {
  height: 100%;
}
.fs-comparison-slider__control input::-webkit-slider-thumb {
  appearance: none;
  height: 100%;
  background: transparent;
  cursor: pointer;
  width: 0.5em;
  box-shadow: none;
}
.fs-comparison-slider__image {
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0;
  right: 0;
  left: 0;
  bottom: 0;
}
.fs-comparison-slider__image img {
  object-fit: cover;
}
.fs-comparison-slider__image--top-image {
  clip-path: inset(0 0 0 5%);
}
</style>
</head>
<body>
  <div class="wrapper">
<div class="fs-comparison-slider">
          <img class="fs-comparison-slider__image" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/74321/dogs-before.jpg"/>
          <div class="fs-comparison-slider__bar" data-comparison-slider-bar></div>
          <div class="fs-comparison-slider__control">
            <input type="range" min="0" max="1000" value="50" data-comparison-slider-control>
          </div>
          <img class="fs-comparison-slider__image fs-comparison-slider__image--top-image" data-comparison-slider-top-image src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/74321/dogs-after.jpg"/>
        </div>    
</div>
  <script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js'></script>
      <script>
const ATTR = {
  CONTROL: 'data-comparison-slider-control',
  BAR: 'data-comparison-slider-bar',
  TOP_IMAGE: 'data-comparison-slider-top-image' };


const SELECTOR = {
  CONTROL: $(`[${ATTR.CONTROL}]`),
  BAR: $(`[${ATTR.BAR}]`),
  TOP_IMAGE: $(`[${ATTR.TOP_IMAGE}]`) };


SELECTOR.CONTROL.on("input change", e => {
  const percentLeft = `${e.target.value / 10}%`;
  SELECTOR.BAR.css({ 'left': percentLeft });
  SELECTOR.TOP_IMAGE.css({ 'clip-path': `inset(0 0 0 ${percentLeft})` });
});
    </script>
</body>
</html>

13. By asifur

Made by asifur. Basic Image Comparison Slider. Source

<!DOCTYPE html>
<html lang="en" >
<head>
  <meta charset="UTF-8">
  <title></title>
<style>
body {
  display: grid;
  place-items: center;
  min-height: 100vh;
}
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  --width: 30vw;
  --height: 80vh;
}

.container {
  position: relative;
  width: var(--width);
  height: var(--height);
}

.img-after,
.img-before {
  position: absolute;
  width: var(--width);
  height: var(--height);
}

.img-before {
  width: 15vw;
  overflow: hidden;
}

img {
  width: var(--width);
  height: var(--height);
  object-fit: cover;
}

.slider {
  width: 0.2rem;
  background-color: white;
  height: 80vh;
  z-index: 1;
  position: absolute;
  top: 0;
  left: 50%;
  transform: translate(-50%, 0%);
  pointer-events: none;
}

@media (max-width: 700px) {
  * {
    --width: 70vw;
  }
}
</style>
</head>
<body>
  <!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>image slider</title>
    <link rel="stylesheet" href="style.css" />
  </head>
  <body>
    <div class="container">
      <div class="img-after">
        <img
          class="after"
          src="https://i.postimg.cc/WzbMWbGn/pexels-jeffrey-czum-2904142-Convert-Image.jpg"
          alt=""
        />
      </div>
      <div class="img-before">
        <img class="before" src="https://i.postimg.cc/02P3vpfW/pexels-jeffrey-czum-2904142.jpg" alt="" />
      </div>
      <div class="slider"></div>
    </div>
      <script>
//check if a user is visiting with a pc or not
if (window.screen.width <= 800) {
  alert("Visit this with pc to see the effect!");
}

const slider = document.querySelector(".slider");
const before = document.querySelector(".img-before");
const after = document.querySelector(".img-after");
const container = document.querySelector(".container");

function dragmyImage(e) {
  let xPos = e.layerX;

  //take the image container width for different device
  let containerSize = container.offsetWidth;

  //modify the before image width size with the bar
  before.style.width = xPos + "px";
  slider.style.left = xPos + "px";

  //if the slider bar is close to the image edge pop the bar to the edge
  if (xPos < 20) {
    before.style.width = 0;
    slider.style.left = 0;
  }
  if (xPos + 20 > containerSize) {
    before.style.width = containerSize + "px";
    slider.style.left = containerSize + "px";
  }
}

container.addEventListener("mousemove", dragmyImage);
//for mobile
container.addEventListener("touchmove", dragmyImage);
    </script>
</body>
</html>