Skip to main content
Homepage
Code Showcase

Javascript Before and After Slider

A simple lightweight pure JavaScript script to create before and after image comparisons.

JavaScript

Javascript Before and After Slider

A simple lightweight pure JavaScript script to create before and after image comparisons.

This is fully compatible with modern browsers and requires no external dependencies.

You can view this project on Ben's GitHub account: https://github.com/benhall14/javascript-before-and-after-slider

Javascript Before & After Slider

A lightweight, dependency-free before/after comparison slider for plain JavaScript projects.

This package ships a browser-ready build in the dist folder and supports npm module imports as well as CDN or static-file use.

Installation

npm install javascript-before-and-after-slider

Package contents

The published package includes:

  • dist/before-and-after-slider.js
  • dist/before-and-after-slider.css

The JavaScript entry is configured as the package entry in package.json. In a browser, it initializes [data-slider] elements automatically when the page loads.

Quick start

<link rel="stylesheet" href="./dist/before-and-after-slider.css" />
<script src="./dist/before-and-after-slider.js"></script>

<div
  data-slider
  data-slider-media-1="./images/before.jpg"
  data-slider-media-2="./images/after.jpg"
></div>

The script discovers every element with data-slider and builds the slider UI for you.

npm module usage

The package can also be imported as a module. The default export provides initSlider, initAll, and observe:

// ES Modules
import Slider from 'javascript-before-and-after-slider';

Slider.initAll();
// CommonJS
const Slider = require('javascript-before-and-after-slider');

Slider.initAll();

The module does not initialize anything when imported outside a browser. In a browser, it still supports the plain <script> usage and automatically initializes [data-slider] elements.

The script also injects its own CSS automatically if needed, so including the CSS file is optional for basic use. Keeping the stylesheet in the page is still recommended when you want explicit control over styling and asset loading.

Basic usage

<div
  data-slider
  data-slider-media-1="before.jpg"
  data-slider-media-2="after.jpg"
  data-start="50"
  data-orientation="horizontal"
></div>

Supported attributes

  • data-slider — marks the element as a slider
  • data-slider-media-1 — first media source
  • data-slider-media-2 — second media source
  • data-start — initial comparison position in percent, default 50
  • data-orientationhorizontal or vertical
  • data-label-before — show a before label
  • data-label-after — show an after label
  • data-label-text-before — custom before label text
  • data-label-text-after — custom after label text
  • data-autoslide — enable automatic sliding
  • data-autoslide-interval — interval in seconds
  • data-move-on-hover — move the comparison on hover
  • data-slide-on-scroll — tie movement to page scroll

Example with labels

<div
  data-slider
  data-slider-media-1="before.jpg"
  data-slider-media-2="after.jpg"
  data-label-before="yes"
  data-label-after="yes"
  data-label-text-before="Before"
  data-label-text-after="After"
></div>

Images, videos and embeds

The library supports image sources, video sources, and embedded media such as YouTube or Vimeo URLs.

<div
  data-slider
  data-slider-media-1="./images/before.mp4"
  data-slider-media-2="./images/after.mp4"
  data-media-1-type="video"
  data-media-2-type="video"
></div>
<div
  data-slider
  data-slider-media-1="https://www.youtube.com/watch?v=dQw4w9WgXcQ"
  data-slider-media-2="https://example.com/after.jpg"
></div>

Manual initialization

When using npm, the default export provides the initialization API:

import Slider from 'javascript-before-and-after-slider';

const slider = Slider.initSlider(document.querySelector('[data-slider]'));
// slider.destroy() to remove the generated slider

The equivalent CommonJS form is:

const Slider = require('javascript-before-and-after-slider');

const slider = Slider.initSlider(document.querySelector('[data-slider]'));

For a browser script or CDN installation, the same API is available through window:

<script src="./dist/before-and-after-slider.js"></script>
<script>
  const slider = CBASP_initSlider(document.querySelector('[data-slider]'));
  // slider.destroy() to remove the generated slider
</script>

You can also initialize all sliders on a page. With npm:

Slider.initAll();

With a browser script:

CBASP_initAll();

To observe dynamically inserted sliders, use Slider.observe(document.body) with npm or:

CBASP_observe(document.body);

Styling

The package exposes CSS variables for common customisation:

[data-slider] {
  --cbasp-max-width: 900px;
  --cbasp-aspect: 16 / 9;
  --cbasp-bar-color: #ffffff;
  --cbasp-bar-width: 4px;
  --cbasp-handle-bg: #ffffff;
  --cbasp-handle-border: #3b82f6;
  --cbasp-icon-color: #3b82f6;
  --cbasp-label-bg: rgba(0, 0, 0, 0.6);
  --cbasp-label-color: #ffffff;
  --cbasp-radius: 12px;
}

Notes for npm release

  • The package is intentionally small and dependency-free.
  • The public API is HTML-first: create a [data-slider] container and provide data-slider-media-* attributes.
  • The browser bundle lives under dist and is what npm consumers should import.
  • This repository is best used as a static asset package or a simple JavaScript library for non-module sites.

License

MIT

The value is specified in seconds.

Example:

<div
    data-slider
    data-slider-media-1="before.jpg"
    data-slider-media-2="after.jpg"
    data-autoslide="yes"
    data-autoslide-interval="5"
></div>

For a faster demonstration:

data-autoslide-interval="2"

For a slower presentation:

data-autoslide-interval="8"

Recommended auto-slide configuration

For a landing-page demonstration:

<div
    data-slider
    data-slider-media-1="images/before.jpg"
    data-slider-media-2="images/after.jpg"
    data-start="50"
    data-autoslide="yes"
    data-autoslide-interval="5"
    data-label-before="yes"
    data-label-after="yes"
    data-label-text-before="BEFORE"
    data-label-text-after="AFTER"
></div>

Scroll-Driven Sliding

The slider can also respond to page scrolling.

Enable:

data-slide-on-scroll="yes"

Example:

<div
    data-slider
    data-slider-media-1="before.jpg"
    data-slider-media-2="after.jpg"
    data-slide-on-scroll="yes"
></div>

This is particularly useful for:

  • long landing pages
  • case studies
  • portfolio pages
  • product demonstrations
  • animated storytelling sections

Scroll + labels

<div
    data-slider
    data-slider-media-1="images/before.jpg"
    data-slider-media-2="images/after.jpg"
    data-slide-on-scroll="yes"
    data-label-before="yes"
    data-label-after="yes"
    data-label-text-before="BEFORE"
    data-label-text-after="AFTER"
></div>

Images

The normal use case is two images with matching dimensions/aspect ratios.

<div
    data-slider
    data-slider-media-1="/images/before.jpg"
    data-slider-media-2="/images/after.jpg"
></div>

Best practice

For the cleanest comparison:

  • use the same dimensions
  • use the same crop
  • use the same aspect ratio
  • use images showing the same subject
  • avoid changing the camera position between Before and After

For example:

before.jpg   1600 × 900
after.jpg    1600 × 900

is preferable to:

before.jpg   1600 × 900
after.jpg    1200 × 1200

Video

The same media configuration can be used for video where supported by the build.

Example:

<div
    data-slider
    data-slider-media-1="/video/before.mp4"
    data-slider-media-2="/video/after.mp4"
></div>

Where explicit media type configuration is required, use the media-type attributes supported by the build.

A video comparison is useful for:

  • motion graphics
  • animation
  • restoration
  • video colour grading
  • property walkthroughs
  • visual effects
  • editing demonstrations

YouTube and Vimeo

For hosted video platforms, provide the relevant URL as the media source where supported.

Example:

<div
    data-slider
    data-slider-media-1="https://www.youtube.com/watch?v=VIDEO_ID_1"
    data-slider-media-2="https://www.youtube.com/watch?v=VIDEO_ID_2"
></div>

Vimeo example:

<div
    data-slider
    data-slider-media-1="https://vimeo.com/VIDEO_ID_1"
    data-slider-media-2="https://vimeo.com/VIDEO_ID_2"
></div>

Platform video behaviour can differ from local <video> elements because playback, autoplay, browser policies and cross-origin restrictions are controlled by the video provider.


Appearance and Styling

The self-contained build supports configuration through data attributes for common visual settings.

Bar colour

data-bar-color="#b9f4ff"

Example:

<div
    data-slider
    data-slider-media-1="before.jpg"
    data-slider-media-2="after.jpg"
    data-bar-color="#b9f4ff"
></div>

Bar width

data-bar-width="4"

Example:

data-bar-width="4"

A thinner divider:

data-bar-width="2"

A heavier divider:

data-bar-width="6"

Handle size

data-handle-size="44"

Example:

<div
    data-slider
    data-slider-media-1="before.jpg"
    data-slider-media-2="after.jpg"
    data-handle-size="44"
></div>

Larger handle:

data-handle-size="56"

Smaller handle:

data-handle-size="36"

Handle background

data-handle-bg="#ffffff"

Example:

data-handle-bg="#ffffff"

Handle border

data-handle-border="#b9f4ff"

Example:

data-handle-border="#b9f4ff"

Handle icon colour

data-icon-color="#b9f4ff"

Example:

data-icon-color="#b9f4ff"

Handle icon

The build supports the configured handle icon styles.

Example:

data-icon="arrows"

Border radius

data-border-radius="16"

Example:

<div
    data-slider
    data-slider-media-1="before.jpg"
    data-slider-media-2="after.jpg"
    data-border-radius="16"
></div>

Square corners:

data-border-radius="0"

Rounded:

data-border-radius="24"

Shadow

Enable:

data-shadow="yes"

Disable:

data-shadow="no"

Example:

<div
    data-slider
    data-slider-media-1="before.jpg"
    data-slider-media-2="after.jpg"
    data-shadow="yes"
></div>

Complete Examples

Example 1 — Minimal

<div
    data-slider
    data-slider-media-1="before.jpg"
    data-slider-media-2="after.jpg"
></div>

Example 2 — Standard Before & After

<div
    data-slider
    data-slider-media-1="images/before.jpg"
    data-slider-media-2="images/after.jpg"
    data-start="50"
    data-label-before="yes"
    data-label-after="yes"
    data-label-text-before="BEFORE"
    data-label-text-after="AFTER"
></div>

Example 3 — Website redesign

<div
    data-slider
    data-slider-media-1="images/website-old.jpg"
    data-slider-media-2="images/website-new.jpg"
    data-start="50"
    data-label-before="yes"
    data-label-after="yes"
    data-label-text-before="OLD WEBSITE"
    data-label-text-after="NEW WEBSITE"
    data-border-radius="16"
    data-shadow="yes"
></div>

Example 4 — Move on hover

<div
    data-slider
    data-slider-media-1="images/before.jpg"
    data-slider-media-2="images/after.jpg"
    data-start="50"
    data-move-on-hover="yes"
    data-label-before="yes"
    data-label-after="yes"
></div>

Example 5 — Auto-sliding

<div
    data-slider
    data-slider-media-1="images/before.jpg"
    data-slider-media-2="images/after.jpg"
    data-autoslide="yes"
    data-autoslide-interval="5"
    data-label-before="yes"
    data-label-after="yes"
></div>

Example 6 — Scroll-controlled

<div
    data-slider
    data-slider-media-1="images/before.jpg"
    data-slider-media-2="images/after.jpg"
    data-slide-on-scroll="yes"
    data-label-before="yes"
    data-label-after="yes"
></div>

Example 7 — Vertical

<div
    data-slider
    data-slider-media-1="images/top.jpg"
    data-slider-media-2="images/bottom.jpg"
    data-orientation="vertical"
    data-start="50"
    data-label-before="yes"
    data-label-after="yes"
></div>

Example 8 — Branded styling

<div
    data-slider
    data-slider-media-1="images/before.jpg"
    data-slider-media-2="images/after.jpg"
    data-start="50"
    data-label-before="yes"
    data-label-after="yes"
    data-label-text-before="BEFORE"
    data-label-text-after="AFTER"
    data-bar-color="#b9f4ff"
    data-bar-width="4"
    data-handle-size="48"
    data-handle-bg="#ffffff"
    data-handle-border="#b9f4ff"
    data-icon-color="#b9f4ff"
    data-icon="arrows"
    data-border-radius="16"
    data-shadow="yes"
></div>

Multiple Sliders on One Page

Multiple sliders can use the same JavaScript file.

<div
    data-slider
    data-slider-media-1="images/kitchen-before.jpg"
    data-slider-media-2="images/kitchen-after.jpg"
></div>

<div
    data-slider
    data-slider-media-1="images/bathroom-before.jpg"
    data-slider-media-2="images/bathroom-after.jpg"
></div>

<div
    data-slider
    data-slider-media-1="images/garden-before.jpg"
    data-slider-media-2="images/garden-after.jpg"
></div>

<script src="/assets/conobe-before-after-slider.js"></script>

Each element is initialised independently.

This means every slider can have different settings:

<div
    data-slider
    data-slider-media-1="before-1.jpg"
    data-slider-media-2="after-1.jpg"
    data-move-on-hover="yes"
></div>

<div
    data-slider
    data-slider-media-1="before-2.jpg"
    data-slider-media-2="after-2.jpg"
    data-autoslide="yes"
    data-autoslide-interval="4"
></div>

<div
    data-slider
    data-slider-media-1="before-3.jpg"
    data-slider-media-2="after-3.jpg"
    data-orientation="vertical"
></div>

Using JavaScript Dynamically

Because the slider is generated by JavaScript, it can also be added to the DOM dynamically.

For example:

<div id="my-slider"></div>

Then populate the configuration:

const element = document.getElementById('my-slider');

element.setAttribute('data-slider', '');
element.setAttribute('data-slider-media-1', 'before.jpg');
element.setAttribute('data-slider-media-2', 'after.jpg');

After adding a slider dynamically, call the library's initialisation function if the build is not automatically observing DOM changes.


Initialisation and API

The library exposes initialisation functionality for pages that need more control.

Automatic initialisation

For normal HTML pages, simply include:

<script src="/assets/conobe-before-after-slider.js"></script>

The library will automatically discover [data-slider] elements.


Manual initialisation

Where supported by the build, the public initialisation methods can be used:

CBASP_initAll();

This tells the library to initialise all matching slider elements.

For a specific element:

CBASP_initSlider(document.querySelector('[data-slider]'));

Example:

const slider = document.querySelector('#my-slider');

CBASP_initSlider(slider);

Destroying a Slider

When removing a slider from a page, it can be useful to destroy its generated state first.

Where supported:

sliderInstance.destroy();

This is particularly useful for:

  • SPA navigation
  • modal windows
  • AJAX content
  • Livewire updates
  • Vue/React components
  • dynamically replaced content

Recommended HTML Patterns

Recommended production pattern

Keep the markup simple:

<div
    data-slider
    data-slider-media-1="/images/project-before.webp"
    data-slider-media-2="/images/project-after.webp"
    data-label-before="yes"
    data-label-after="yes"
    data-label-text-before="BEFORE"
    data-label-text-after="AFTER"
></div>

Avoid recreating the internal slider structure yourself.

The point of this build is that the internal structure belongs to the library.


Embedding on a Demo Site

A very simple demo page can be:

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Conobe Before & After Slider Demo</title>
</head>

<body>

    <h1>Before & After Slider</h1>

    <div
        data-slider
        data-slider-media-1="/images/before.jpg"
        data-slider-media-2="/images/after.jpg"
        data-label-before="yes"
        data-label-after="yes"
        data-label-text-before="BEFORE"
        data-label-text-after="AFTER"
    ></div>

    <script src="/assets/conobe-before-after-slider.js"></script>

</body>
</html>

No:

<link rel="stylesheet" href="slider.css">

is required when using the self-contained build.

No:

<script src="jquery.js"></script>

is required.

No:

<script src="wordpress.js"></script>

is required.

The demo site therefore has a very small integration footprint.


Accessibility

When implementing sliders on a production site, consider:

  • meaningful image content
  • useful alternative text
  • keyboard interaction
  • sufficient contrast
  • visible focus states
  • avoiding motion that cannot be paused where appropriate

For example, the surrounding page can provide context:

<figure>
    <div
        data-slider
        data-slider-media-1="/images/before.jpg"
        data-slider-media-2="/images/after.jpg"
        data-label-before="yes"
        data-label-after="yes"
        data-label-text-before="BEFORE"
        data-label-text-after="AFTER"
    ></div>

    <figcaption>
        Kitchen renovation — comparison of the original and completed room.
    </figcaption>
</figure>

Troubleshooting

Slider does not appear

Check that the container has:

data-slider

and that both media attributes are present:

data-slider-media-1="before.jpg"
data-slider-media-2="after.jpg"

Also check the browser developer console for JavaScript errors.


Images are not loading

Check the image URL directly.

For example:

data-slider-media-1="/images/before.jpg"

must point to a real accessible resource.

Common problems include:

  • incorrect relative path
  • case-sensitive filename mismatch
  • missing image
  • server permissions
  • HTTPS/HTTP mixed content
  • hotlink protection

The images do not line up

Use images with matching:

  • width
  • height
  • aspect ratio
  • crop
  • camera position

For example:

Before: 1600 × 900
After:  1600 × 900

The slider is too small

The slider fills its containing element, so give the parent/container an appropriate width.

For example:

<div style="max-width: 1200px; margin: 0 auto;">
    <div
        data-slider
        data-slider-media-1="before.jpg"
        data-slider-media-2="after.jpg"
    ></div>
</div>

The slider is too tall or short

Use media with the desired aspect ratio and make sure the containing layout is not imposing an unexpected height.


Auto-slide is not working

Check:

data-autoslide="yes"

and, if required:

data-autoslide-interval="5"

Also check whether browser/user motion policies or the specific media type affect the behaviour.


Attribute Reference

The following is the intended public configuration surface.

Attribute Example Purpose
data-slider data-slider Marks an element as a slider
data-slider-media-1 before.jpg First media source
data-slider-media-2 after.jpg Second media source
data-start 50 Initial slider position
data-orientation horizontal Horizontal or vertical slider
data-label-before yes Enable Before label
data-label-after yes Enable After label
data-label-text-before BEFORE Before label text
data-label-text-after AFTER After label text
data-label-position top Label placement
data-move-on-hover yes Move slider with mouse position
data-slide-on-scroll yes Link slider movement to scrolling
data-autoslide yes Enable automatic movement
data-autoslide-interval 5 Auto-slide interval
data-bar-color #b9f4ff Divider colour
data-bar-width 4 Divider width
data-handle-size 44 Handle size
data-handle-bg #ffffff Handle background
data-handle-border #b9f4ff Handle border
data-icon-color #b9f4ff Handle icon colour
data-icon arrows Handle icon
data-border-radius 16 Corner radius
data-shadow yes Slider shadow

Recommended Default

For most Before & After demonstrations, this is a good starting point:

<div
    data-slider
    data-slider-media-1="/images/before.jpg"
    data-slider-media-2="/images/after.jpg"
    data-start="50"
    data-orientation="horizontal"
    data-label-before="yes"
    data-label-after="yes"
    data-label-text-before="BEFORE"
    data-label-text-after="AFTER"
    data-move-on-hover="no"
    data-slide-on-scroll="no"
    data-autoslide="no"
    data-bar-color="#b9f4ff"
    data-bar-width="4"
    data-handle-size="44"
    data-handle-bg="#ffffff"
    data-handle-border="#b9f4ff"
    data-icon-color="#b9f4ff"
    data-icon="arrows"
    data-border-radius="16"
    data-shadow="yes"
></div>

This gives a conventional, manually controlled comparison with clear labels and branded styling.


One-File Installation

The final intended integration is:

your-website/
├── assets/
│   └── conobe-before-after-slider.js
├── images/
│   ├── before.jpg
│   └── after.jpg
└── index.html

index.html:

<div
    data-slider
    data-slider-media-1="/images/before.jpg"
    data-slider-media-2="/images/after.jpg"
    data-label-before="yes"
    data-label-after="yes"
    data-label-text-before="BEFORE"
    data-label-text-after="AFTER"
></div>

<script src="/assets/conobe-before-after-slider.js"></script>

That is the key advantage of the self-contained build:

One JavaScript file + one simple HTML element = complete Before & After slider.

Requirements

None

License

Copyright (c) Benjamin Hall, ben@conobe.co.uk https://conobe.co.uk

Licensed under the MIT license

Donate?

If you find this project helpful or useful in anyway, please consider getting me a cup of coffee - It's really appreciated :)

Donate

1) Basic

2) Start position

3) Vertical orientation

4) Move on hover

5) Auto slide

6) Scroll-driven sliding

7) Video

8) YouTube embed

9) Styled bar and handle

10) Rounded + shadow

11) Full branded example

Ready to start your project?
Contact us today for a free consultation.
Contact us today for a free consultation.