Image Compare

A tiny, zero-dependency web component for comparing two images using a slider. Built with a focus on accessibility, performance, and progressive enhancement.

For more information you can install it on npm, view the source onGitHub, or read an article about how it was built.

A friendly illustrated cloud character with eyes on a red-pink background. A friendly illustrated cloud character with eyes surrounded by a variety of icons (including check marks, stars, code brackets, buttons, hearts, a checkbox, and many more) on a blue background.

How it works

Image Compare layers your two images on top of each other. Then it applies a percentage-based CSS clipping mask to the top image.

The slider control is built using a HTML range input with special styles and positioning applied via CSS. When the slider value changes the clipping mask is updated using a custom property.

Accessibility

Since Image Compare uses a native HTML range input it can be controlled via keyboard and assistive technologies.

The input has a visually hidden label which is exposed to screen readers and other assistive technologies without affecting the visual design. This can be customized with the label-text attribute.

When using Image Compare careful thought should be given to the label text, as well as the alt text on the images being compared.

Performance

Image Compare has zero dependencies and weighs in at just 1.5 kB (minified and gzipped) including markup, interactivity, and styles.

Progressive Enhancement

If the JavaScript is slow to load or fails to load, the two images will display vertically stacked on the page so they can still be compared.

Browser Support

Image Compare works in all modern browsers. (It will not work in IE11 since IE11 does not have support for custom elements or custom properties. In IE11 it should fall back to displaying two stacked images.)

Usage

The quickest way to get started is to load Image Compare as a script tag:

<script src="https://unpkg.com/@cloudfour/image-compare/dist/index.min.js"></script>

Then you can use Image Compare like a regular HTML element:

<image-compare label-text="Screen Reader Label Text">
  <img slot="image-1" alt="Alt Text" src="path/to/image.jpg"/>
  <img slot="image-2" alt="Alt text" src="path/to/image.jpg"/>
</image-compare>

You can also install Image Compare as an npm package:

npm i @cloudfour/image-compare

And then import it into your code:

import '@cloudfour/image-compare'

Slots

It expects two images to be passed into the image-1 and image-2 slots. (image-1 will be on the left, and image-2 will be on the right.)

For best results both images should have the same aspect ratio. The second image will be cropped to the height of the first image.

Image Compare also works well with the responsive images syntax allowing you to optimize your images for different devices and screen sizes.

Custom Label Text

There is an optional label-text attribute which can be used to provide extra context to screen reader users and other assistive technologies. If left unset it will default to the following:

Control how much of each overlapping image is shown. 0 means the first image is completely hidden and the second image is fully visible. 100 means the first image is fully visible and the second image is completely hidden. 50 means both images are half-shown, half-hidden.

Styling

The image-compare component can be styled using custom properties. Here is the full list of custom properties and their default values:

--thumb-background-color: hsla(0, 0%, 100%, 0.9);
--thumb-background-image: url('data:image/svg+xml;utf8,<svg viewbox="0 0 60 60"  width="60" height="60" xmlns="http://www.w3.org/2000/svg"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="4" d="M20 20 L10 30 L20 40"/><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="4" d="M40 20 L50 30 L40 40"/></svg>');
--thumb-size: clamp(3em, 10vmin, 5em);
--thumb-radius: 50%;
--thumb-border-color: hsla(0, 0%, 0%, 0.9);
--thumb-border-size: 2px;

--focus-width: var(--thumb-border-size);
--focus-color: hsl(200, 100%, 80%);

--border-width: 2px;
--border-color: hsla(0, 0%, 0%, 0.9);

Manifest Files

Additional manifest documentation files have been automatically generated for this component using the Web Component Analyzer:

Contributing

Notice an issue or have an idea for an improvement? Please create an issue on GitHub.


Built with love and web components by Cloud Four.