compare-images-slider
v1.1.0
Published
A simple slider for comparing two images.
Maintainers
Readme
↔️ Compare Images Slider

A simple slider for comparing two images visually.
Features
- Lightweight
- Minimal DOM depth
- No dependencies
- Mobile friendly
- Vertical slider
- Inertia physics with capped, natural-feeling flicks
- Bounce back
- Keyboard accessible (W3C APG Window Splitter)
- Custom element, no shadow DOM
- Customizable via CSS
Demo
Installation
npm install compare-images-slideror use the CDN:
<script src="https://unpkg.com/compare-images-slider/dist/compare-images-slider.min.js"></script>
<link
rel="stylesheet"
href="https://unpkg.com/compare-images-slider/dist/compare-images-slider.min.css"
/>Usage
<div class="js-compare-images-slider compare-images-slider">
<img src="img.jpg" alt="" />
<div class="frame">
<img src="img-alt.jpg" alt="" />
</div>
<span class="handle"></span>
</div>⚠️ Note: Don't be lazy and please set the intrinsic dimensions of the images. This eliminates layout shifts and will ensure the slider works as expected.
import CompareImagesSlider from "compare-images-slider";
const slider = document.querySelector(".js-compare-images-slider");
const compareImagesSlider = new CompareImagesSlider(slider);If you are loading the script asynchronously, you can listen for the CompareImagesSliderLoaded event to initialize the slider:
document.addEventListener("CompareImagesSliderLoaded", function () {
const slider = document.querySelector(".js-compare-images-slider");
const compareImagesSlider = new CompareImagesSlider(slider);
});@import "node_modules/compare-images-slider/src/styles/index.scss";Custom element
The same markup wrapped in a <compare-images-slider> tag upgrades itself — no
JavaScript call needed. It uses light DOM (no shadow root), so the images, frame
and handle stay fully stylable. Options are read from attributes (bare, data-*
or kebab-case):
<compare-images-slider inertia initial-position="35">
<img src="img.jpg" alt="" />
<div class="frame">
<img src="img-alt.jpg" alt="" />
</div>
<span class="handle"></span>
</compare-images-slider>Accessibility
The handle is a focusable role="separator" implementing the
W3C APG Window Splitter pattern
with aria-valuenow/min/max, aria-orientation and aria-controls. Once
focused: arrow keys move by step, Page Up/Down by pageStep, Home/End jump to
the extremes, and double-click snaps to the nearest extreme.
Options
// Default options
const options = {
inertia: false, // inertia physics, you can flick the handle
friction: 0.9, // the friction of the inertia
bounce: false, // will bounce back when inertia is enabled and the boundary is reached
bounceFactor: 0.1, // the force of the bounce
maxFlickVelocity: 0.5, // cap on flick velocity (% per ms), tames hard flicks
vertical: false, // vertical slider
onlyHandle: true, // only the handle is draggable
initialPosition: 50, // starting position (0-100)
step: 5, // arrow-key step (percent)
pageStep: 25, // Page Up/Down step (percent)
};
new CompareImagesSlider(slider, options);Available attribute options (bare, data-* or kebab-case):
vertical- vertical sliderinertia,bounce,only-handle- booleansfriction,bounce-factor,max-flick-velocity,initial-position,step,page-step- numbers
<div class="js-compare-images-slider compare-images-slider" vertical>
<img src="img.jpg" alt="" />
<div class="frame">
<img src="img-alt.jpg" alt="" />
</div>
<span class="handle"></span>
</div>Development
npm install
npm test # unit tests (node:test)
npm run lint
npm run buildMade with ❤️ by @stamat.
