Creating an Image Comparison Slider with HTML, CSS, and JavaScript
Tags: webdev, javascript, programming, html
Published: 2023-10-08 15:15:40

Hello Frands 👋☕👋
-----------

Image comparison sliders are a useful tool for showcasing differences between two images. Whether you want to display before-and-after photos, highlight changes in a design, or demonstrate the impact of an image filter, a slider can make these comparisons interactive and engaging. In this tutorial, we will create a simple image comparison slider using HTML, CSS, and JavaScript.

## Full Code here

- [Demo](https://mursalfk.github.io/Comparison-Slider/)
- [Code](https://github.com/mursalfk/Comparison-Slider)

## Prerequisites

Before we begin, make sure you have a basic understanding of HTML, CSS, and JavaScript. You should also have a code editor of your choice installed on your computer.

## HTML Structure

Let's start by setting up the basic HTML structure for our image comparison slider:

```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Image Comparison Slider</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <main>
        <!-- Container for the slider -->
        <div class="container">
            <!-- Images to compare -->
            <div class="image-container">
                <img class="image-before slider-image image-1" src="before.jpg" alt="Before Image">
                <img class="image-after slider-image image-2" src="after.jpg" alt="After Image">
            </div>
            <!-- Slider input element -->
            <input type="range" min="0" max="100" value="50" aria-label="Percentage of before photo shown" class="slider">
            <!-- Slider line and handle -->
            <div class="slider-line" aria-hidden="true"></div>
            <div class="slider-button" aria-hidden="true">
                <!-- Slider handle icon (e.g., a draggable circle or button) -->
            </div>
        </div>
    </main>
</body>
</html>
```

In this HTML structure, we have a main container with two images (before and after), a slider input element, a slider line, and a slider handle (button).

## CSS Styling

Now, let's add some CSS to style our image comparison slider. Here's a simplified version of the CSS:

```css
/* Reset some default styles and set up the background color */
*,
*::after,
*::before {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    background-color: #f0f0f0;
}

/* Container styles */
.container {
    position: relative;
    overflow: hidden;
    /* Set initial position for the slider handle (50% in this example) */
    --position: 50%;
}

/* Image container */
.image-container {
    aspect-ratio: 16/9; /* Set your desired aspect ratio */
    /* Style images within the container */
    img {
        width: 100%;
        height: 100%;
        object-fit: cover;
    }
}

/* Slider styles */
.slider {
    position: absolute;
    width: 100%;
    height: 100%;
    /* Hide slider input visually */
    opacity: 0;
}

.slider-line {
    /* Style the slider line */
}

.slider-button {
    /* Style the slider handle */
}
```

This CSS code sets up the basic styling for our image comparison slider. You can customize the styles to match your design preferences.

## The JavaScript Code

Now, let's dive into the JavaScript code that powers our image comparison slider. We'll explain each function step by step.

### 1. `initializeSlider()`

This function initializes the image comparison slider by adding event listeners to the slider input element.

```javascript
function initializeSlider() {
    const slider = document.querySelector('.slider');
    const container = document.querySelector('.container');

    slider.addEventListener('input', function (e) {
        container.style.setProperty('--position', e.target.value + '%');
    });
}
```

Explanation:
- `initializeSlider()` sets up the slider's interactivity.
- We select the slider and container elements using `document.querySelector()`.
- An event listener is added to the slider input element.
- When the slider value changes (`'input'` event), the function updates the `--position` CSS variable to move the slider handle and adjust the before and after image widths accordingly.

### 2. `loadImages()`

This function loads the before and after images when the user selects image files.

```javascript
function loadImages() {
    const file1 = document.querySelector('#imageUpload1').files[0];
    const file2 = document.querySelector('#imageUpload2').files[0];

    if (file1 && file2 && file1.type.startsWith('image/') && file2.type.startsWith('image/')) {
        const imageBefore = document.querySelector('.image-before');
        const imageAfter = document.querySelector('.image-after');

        imageBefore.src = URL.createObjectURL(file1);
        imageAfter.src = URL.createObjectURL(file2);
    } else {
        alert('Please select valid image files.');
    }
}
```

Explanation:
- `loadImages()` is called when the user clicks the "Show Difference" button.
- It retrieves the selected image files using `document.querySelector()` and checks if they are valid image types (using `file.type.startsWith('image/')`).
- If both files are valid, it updates the `src` attribute of the before and after images to display the selected images.
- If any of the conditions are not met, it shows an alert to inform the user.

### 3. `setAspectRatio(imageNumber)`

This function sets the aspect ratio of the images to maintain proper sizing.

```javascript
function setAspectRatio(imageNumber) {
    const imageElement = document.querySelector(`.image-${imageNumber}`);
    const aspectRatio = imageElement.naturalWidth / imageElement.naturalHeight;
    const aspectRatioString = aspectRatio.toString();
    document.querySelector('.image-container').style.setProperty('--aspect-ratio', aspectRatioString);
}
```

Explanation:
- `setAspectRatio(imageNumber)` sets the aspect ratio for a given image (either before or after).
- It calculates the aspect ratio by dividing the natural width by the natural height of the image.
- Then, it updates the `--aspect-ratio` CSS variable of the image container to maintain the correct aspect ratio.

### 4. `selectImage(imageNumber)`

This function is called when the user selects an image file to upload.

```javascript
function selectImage(imageNumber) {
    const inputElement = document.querySelector(`#imageUpload${imageNumber}`);
    const file = inputElement.files[0];

    if (file && file.type.startsWith('image/')) {
        if (imageNumber === 1) {
            // Update file1 and file1Selected
        } else {
            // Update file2 and file2Selected
        }

        if (file1Selected && file2Selected) {
            // Enable the "Show Difference" button
        }
    } else {
        alert('Please select valid image files.');
    }
}
```

Explanation:
- `selectImage(imageNumber)` is called when the user selects an image to upload (either before or after).
- It retrieves the selected file and checks if it's a valid image type.
- Depending on whether it's the before or after image, it updates the respective file variables (`file1` or `file2`) and their selected status.
- If both files are selected and valid, it enables the "Show Difference" button. If not, it may display an alert for invalid image files.

### 5. HTML and CSS

In our HTML structure, we have omitted the header and container for the slider as well as the buttons for selecting images and showing the difference. These elements should be defined in your HTML document, and you can refer to the code provided earlier.

The CSS (in a separate `style.css` file) is responsible for styling the components, including setting the aspect ratio of the image container, defining button styles, and handling responsive design.

## Conclusion

By breaking down the JavaScript functions used in our image comparison slider, we hope you have gained a better understanding of how to create this interactive feature. You can now build your own image comparison sliders and enhance your web projects with this engaging user interface element.

Happy Coding 🍀