DEV Community

Cover image for Image Comparison Slider in CSS Only (without using JavaScript)
Prahalad S
Prahalad S

Posted on • Edited on

Image Comparison Slider in CSS Only (without using JavaScript)

Image Comparison Slider in CSS without using JavaScript

Image description

In Previous tutorial I made the 'Image Comparison Slider' with one line of JavaScript code. Here we are going to do without using JavaScript.

Lets create input range slider and two divs below it with class names '.front', '.back' inside parent div with class name ''.img-before-after''.

Assign inline CSS variable to input range style="--timeline:--_slider"

<div class="img-before-after">
  <input type="range" class="range" style="--timeline:--_slider" value="50">
  <div class="front"></div>
  <div class="back"></div>
</div>
Enter fullscreen mode Exit fullscreen mode

Lets create CSS. First lets create CSS custom @property --_slider with syntax: number, inherits: true, and initial-value: 0

@property --_slider {
    syntax: "<number>";
    inherits: true;
    initial-value: 0;
}
Enter fullscreen mode Exit fullscreen mode

Lets declare global variables.

:root {
    --min-size: 0%; // min size when the slider is 0 (to left)
    --max-size: 100%; // max size when the slider is 100% (to right)
}
Enter fullscreen mode Exit fullscreen mode

Tricky part: Lets append the slider value to width of .front div dynamically using CSS variables(--min-size and --max-size values with --_slider). Also assign Property variable name --_slider to timeline-scope, and animation-name and animation-timeline and create @keyframe

:root {
    --min-size: 0%;
    --max-size: 100%;
    --width: calc(var(--max-size)*var(--_slider) + var(--min-size)*(1 - var(--_slider)));
    animation: linear;
    animation-name: --_slider;
    timeline-scope: --_slider;
    animation-timeline: --_slider;
}

@keyframes --_slider {
    0% {
        --_slider: 1;
    }
}

Enter fullscreen mode Exit fullscreen mode

Create CSS for elements img-before-after, input-range, input-slider-thumb.

body {
    background: #d6d6d6;
}

.img-before-after {
    position: relative;
    width: 900px;
    height: 600px;
}

input[type="range"] {
    background: transparent;
    width: 100%;
    height: 100%;
    margin: 0;
    outline: none;
    position: absolute;
    z-index: 2;
    -webkit-appearance: none;
    overflow: hidden;
}

input[type="range"]::-webkit-slider-thumb {
    width: 10px;
    height: 600px;
    cursor: pointer;
    -webkit-appearance: none;
    background: black;
    view-timeline: var(--timeline) inline;
}

input[type="range"]::-moz-range-thumb {
    view-timeline: var(--timeline) inline;
}
Enter fullscreen mode Exit fullscreen mode

Lets add background image for both .front and .back divs. Lets assign width property value to var(--width). We are appending this from slider value where we declared in global variables in :root.

.front, .back {
    position: absolute;
    height: 600px;
    width: var(--width);
    background: url("https://shorturl.at/kbKhz") no-repeat;
    background-size: cover;
    z-index: 1;
}
Enter fullscreen mode Exit fullscreen mode

Lets send .back div behind .front div with z-index and make it grayscale.

.back {
    filter: grayscale(1);
    width: 100%;
    z-index: 0;
}
Enter fullscreen mode Exit fullscreen mode

Output:

Image description

Below you can watch how the width is changing in dev tools>computed when we drag the slider range. It wont show the width. After dragging the slider we have to double click on the dimensions in computed and release the mouse, then the width will display like below gif image. Right click on below gif and open image in new tab for more visibility.

Image description

You can try with different variations in CSS like blur, invert etc like below.

.back {
    filter: blur(5px);
    width: 100%;
    z-index: 0;
}
Enter fullscreen mode Exit fullscreen mode

Image description

invert

.back {
    filter: invert(1);
    width: 100%;
    z-index: 0;
}
Enter fullscreen mode Exit fullscreen mode

Image description

Final Output: with grayscale

Image description

Watch Demo

Thank you for watching...

Top comments (0)