Image Comparison Slider - Custom Handle
Same as the Basic, but with some UI customization.
Demo
HTML
<!-- The important part here is the `.container`, two children with an image, and the `range` element -->
<div class="container custom-handle">
<div id="left">
<img src="https://images.unsplash.com/photo-1763236390948-fcc866ddb17a?crop=entropy&cs=srgb&fm=jpg&ixid=M3wzMjM4NDZ8MHwxfHJhbmRvbXx8fHx8fHx8fDE3Njk3MTQ1MjB8&ixlib=rb-4.1.0&q=85&w=800"
width="800"
height="533"
alt="Sample image, rugged sunlit cliffsides with bright blue sky above" />
</div>
<div id="right">
<img src="https://images.unsplash.com/photo-1763236390948-fcc866ddb17a?crop=entropy&cs=srgb&fm=jpg&ixid=M3wzMjM4NDZ8MHwxfHJhbmRvbXx8fHx8fHx8fDE3Njk3MTQ1MjB8&ixlib=rb-4.1.0&q=85&w=800&colorquant=2"
width="800"
height="533"
alt="Sample image, rugged rock being battered by waves with pastel sky above" />
</div>
<input type="range">
</div>CSS
/* Basic slider */
.container {
position: relative;
max-width: 800px;
height: auto;
aspect-ratio: 6 / 4;
display: grid;
place-items: center;
overflow: hidden;
}
/* Overlap the image containers, and stretch the images to fill the container */
div div {
position: absolute;
height: 100%;
left: 0;
right: 0;
}
img {
height: 100%;
object-fit: cover;
}
div div {
position: absolute;
height: 100%;
left: 0;
right: 0;
}
#left img {
object-position: 0 0;
}
#right img {
object-position: 100% 0;
}
/* Setup the `range` element */
input {
--thumb-width: 17px;
width: calc(100% + var(--thumb-width));
z-index: 1;
}
/* Set the anchor position */
#right {
left: anchor(--thumb center);
}
/* Attach the slider handle to the anchor*/
input::-webkit-slider-thumb {
anchor-name: --thumb;
}
input::-moz-range-thumb {
anchor-name: --thumb;
}
input::-ms-thumb {
anchor-name: --thumb;
}
/* Add the fancy handle */
.custom-handle {
/* Customize the `range` element */
input {
/* Effectively hide the track */
-webkit-tap-highlight-color: transparent;
-webkit-appearance: none;
appearance: none;
background-color: transparent;
/* Allow the user to grab the handle anywhere along the dividing line */
height: 100%;
/* Use the "resize" cursor to make the action more intuitive */
cursor: col-resize;
}
/* Give the handle a more obvious demarcation */
#right {
outline: 2px solid rgb(255 255 255 / .5);
border-left: 2px solid rgb(255 255 255 / .5);
}
/* Customize the hdnale itself */
input::-webkit-slider-thumb {
/* Effectively hide the initial look */
-webkit-tap-highlight-color: transparent;
-webkit-appearance: none;
appearance: none;
/* Make sure the handle is easy to grab */
width: 40px;
height: 40px;
/* Add double-arrow SVG icon */
background-image: url(data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20fill%3D%22none%22%20class%3D%22compare__icon%22%20viewBox%3D%220%200%2016%2016%22%3E%3Cpath%20d%3D%22M%206%202%20L%201%208%20L%206%2014%20M%2010%202%20L%2015%208%20L%2010%2014%22%20stroke%3D%22currentColor%22%3E%3C%2Fpath%3E%3C%2Fsvg%3E);
/* Further customize the appearance */
background-color: white;
background-position: center;
background-repeat: no-repeat;
background-size: 70%;
border-radius: 100%;
}
/* Above has to be repeated separately for Mozilla... */
input::-moz-range-thumb {
/* Make sure the handle is easy to grab */
width: 40px;
height: 40px;
/* Add double-arrow SVG icon */
background-image: url(data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20fill%3D%22none%22%20class%3D%22compare__icon%22%20viewBox%3D%220%200%2016%2016%22%3E%3Cpath%20d%3D%22M%206%202%20L%201%208%20L%206%2014%20M%2010%202%20L%2015%208%20L%2010%2014%22%20stroke%3D%22currentColor%22%3E%3C%2Fpath%3E%3C%2Fsvg%3E);
/* Further customize the appearance */
background-color: white;
background-position: center;
background-repeat: no-repeat;
background-size: 70%;
border-radius: 100%;
}
/* And Edge. */
input::-ms-thumb {
/* Make sure the handle is easy to grab */
width: 40px;
height: 40px;
/* Add double-arrow SVG icon */
background-image: url(data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20fill%3D%22none%22%20class%3D%22compare__icon%22%20viewBox%3D%220%200%2016%2016%22%3E%3Cpath%20d%3D%22M%206%202%20L%201%208%20L%206%2014%20M%2010%202%20L%2015%208%20L%2010%2014%22%20stroke%3D%22currentColor%22%3E%3C%2Fpath%3E%3C%2Fsvg%3E);
/* Further customize the appearance */
background-color: white;
background-position: center;
background-repeat: no-repeat;
background-size: 70%;
border-radius: 100%;
}
}JS
No JS required.Baseline
CodePen
See the Pen on CodePen.