Build a reusable before/after image slider with Stimulus

Before and after (image) sliders are great for product showcases, before/after transformations, renovation projects or photo editing results. They’re engaging, interactive, and honestly just fun to use.

Ever thought of building one from scratch? Not complicated at all! In this article, I want to show how to build a simple, reusable Stimulus controller that does just all that. This is how the end result will look like:

As always, the code can be found on GitHub.

It is simple, really

The beauty of this controller is its simplicity. You need three things:

  • a wrapper element;
  • two images (before and after), and;
  • a slider.

That’s it. Here’s it in HTML:

<div data-controller="compare">
  <img data-compare-target="before" src="before.jpg">
  <img data-compare-target="after" src="after.jpg">

  <div data-compare-target="slider"></div>
</div>

The two images are positioned absolutely and the slider sits on top as a draggable handle. The “after” image gets clipped dynamically as you drag.

Here’s that interesting part. It uses clip-path to reveal or hide the after image:

set #position(value) {
  this.positionValue = value
  this.sliderTarget.style.left = `${value * 100}%`
  this.afterTarget.style.clipPath = `inset(0 0 0 ${value * 100}%)`
}

When you drag the slider, it calculates the position relative to the container’s width, then updates both the slider’s left position and the clip-path of the after image. Most of that is done with:

#pointerDown = (event) => {
  if (event.target !== this.sliderTarget) return

  event.preventDefault()

  document.addEventListener("pointermove", this.#pointerMove)
  document.addEventListener("pointerup", this.#pointerUp)
}

Stimulus controllers are meant to be reusable

This controller is a wrapper element plus two images. That’s it. Use cases then are limitless (they generally work great on marketing blogs as well!):

  • product photography; show different angles or colors of the same product
  • photo editing results; before/after with filters, adjustments, or retouching
  • UI redesigns; old interface vs. new interface

You could (should) extend this in several directions. Add keyboard support for accessibility. Include labels (“Before” / “After”) that move with the slider. Add touch support with haptic feedback on mobile.

It is the kind of controller you copy and paste into your projects. Just as it should be.

Product-minded Rails notes

Once a month: straightforward notes on improving UX in Rails—what to simplify, what to measure, and UI/frontend changes that move real usage.

Over to you…

What did you like about this article? Learned something knew? Found something is missing or even broken? 🫣 Let me (and others) know!

Comments are powered by Chirp Form

Want to read me more?