How to create a “Before & After” image slider with CSS and JS
Tags: Tutorial, Image Slider, Before And After, CSS, Frontend

Step by step guide

Step 1. Understand the concept

The concept of this “image slider” is very simple. You only need two components, the image container, and a slider.

The image container is just a regular div, with two images of the same size overlapping each other. One as the“background”, another as the “foreground”.

We will use absolute position to make the foreground image directly on top of the background one. The background image always has 100% width, while the width of the foreground image would change according to user input, making part of the background image appear.

The second component is the “slider”. To make thing simple, we could just make use of the html “range” input element. It allow user to select a value by dragging, between your defined min and max value. The input could be easily retrieved using an event listener in javascript.

<input type="range" min="1" max="100" value="50" class="slider" id="myRange">

for more detail, see https://www.w3schools.com/howto/howto_js_rangeslider.asp

One drawback of using the default slider input is, the styling of it is kind of limited. You cannot go very crazy on the design. If you are looking for a more customisable slider, you might have to build it yourself. However, it is not a focus of this tutorial.

We would make the slider with 100% width and height of the container, and position it on top of the image container. When the user drags the slider, we update the width of the foreground at the same time. Creating an illusion of the user is dragging the image instead.

When the slider value get updated, we will change the width of the foreground

I hope that’s enough explanation. We will jump into the coding now.

Step 2. Create the image container

Let start by creating our container. It is a simple structure with two div inside. Since we don’t want our image to scale based on the div width containing them, we will use apply the image with background-image instead of <img> tag. One important style we need to use is the background-size property, and make sure that the image always stays at the same size.

HTML:

SCSS:

To make thing a little bit easier for this tutorial, I used fixed size for everything.

*If you don’t want to use SCSS, just make the style flat instead of nested

I used two version of the same image (with and without color), so they are perfectly align

Now we have our container, let’s add the slider.

Step 3. Create the slider

Our slider needs to cover the whole image, with a thin white bar “dividing” the before and after part of the image. It could be done by styling the slider and the slider-thumb (the part where you drag). we need to make the default appearance of the slider and the thumb invisible, and then apply our own style on it.

HTML (below the images):

SCSS (with reference to https://www.w3schools.com/howto/howto_js_rangeslider.asp):

If you don’t want to use SCSS, replace @include center with the content in @mixin center , and use .slider::-webkit-slider-thumb to replace the & syntax

I applied a slightly visible grey color background to the slider, and on hover, making the color even more transparent. Creating a “focus” effect when user hover over the image. For the slider-thumb, it is just a white background div with full height of the container.

You might need ::-moz-range-thumb for browser support in firefox

We now have a working slider, let link that up with the width of the foreground image.

Step 4. Add event listener to the slider

The last step is to link up the value from the slider to the width of the foreground image. It is very easy to achieve (since we are using the native html range input as the slider). We could get a value from 1–100 in the event.target.value when we apply event listener.

Then, we just need to select the foreground element, and change the width of it whenever the slider got updated.

JS:

If it didn’t work as expected, try to see if you retrieve the value of the slider correctly, and double check the background-size property of your css

Yeah! The function is working. As a bonus of using the range input, we can even click within the container to make the slider go to the clicked position.

One more thing we could (and probably should) add to the UI is a “drag me” circle icon on the slider, as an indicator that this is a drag-able component.

Step 5 (Optional). Adding a circle thumb on the slider

The native range input has it advantage (easy to implement, easy to retrieve value, etc), but when come to styling, there are not much we could do. As we replace the default “circle” thumb with our white-separating line, we need to add the circle back somehow.

A quick (but dirty) way to do it is to add another element, completely not related to the slider, but is positioned to the center of it, and would “follow” its movement by javascript. And this is exactly what we would do.

HTML:

SCSS:

The after and before element add the two “arrow” inside the circle button

JS:

One more thing we need to do is to make the circle not selectable, so the mouse event always goes to the slider. With some careful positioning and JS, we make the circle thumb move together with the slider.

This is just the same image from above.

And with that, our “before and after” image slider is completed. You can now pick your favourite image and experiment with it. (And thank you Beth Harmon for accompany us through this journey)