Before and after

A draggable divider for comparing an image before and after an edit.

Loading preview…

Install

  1. 1

    Run this command in your Tailwind CSS project. It adds components/ai/before-after.tsx and installs its dependencies.

    $ npx shadcn@latest add https://gradientdeck.com/ai-components/r/before-after.json

Usage & API

Example

before-after.tsx
import { BeforeAfter } from "@/components/ai/before-after"

<BeforeAfter
  before={before}
  after={after}
/>

Props BeforeAfter

PropType & descriptionRequired
beforeReactNodeRequired
afterReactNodeRequired
beforeLabelstringOptional
afterLabelstringOptional
defaultValuenumber0–100, where the divider startsOptional
introbooleanNudge the divider once on mount so people see it moves.Optional
onChange(value: number) => voidOptional
captionReactNodeOptional

Dependencies

  • React
  • Tailwind CSS
  • motion
  • lucide-react
Implementation notes

The slider variant is the whole component. The preview puts an overcast grey landscape on the before side and a warm evening palette on the after side, with the same seed so the ridges stay aligned. The caption reads Relight for golden hour, keep the hills, with the drag hint on the right. intro is on, so the handle demonstrates itself once. Labels stay at Before and After. There is no second layout, no vertical split, and no zoom. The divider is a two-pixel light line with a shadow, and the handle is a blurred circle that scales up while dragging and shows a focus ring. Pointer capture stays on the frame until release, including touches, and the frame uses touch-none so the page does not scroll instead of the wipe.

Choosing a layout

Use it when two frames are the same composition and the useful question is where they differ. Relighting, a cleanup, a background swap, or an upscale against its source all read well as a wipe, because the eye can line up a ridge or a window across the split. The caption slot is there for the instruction that produced the edit, or for a hint such as the preview's Drag or use arrow keys. Keep the two nodes the same aspect. The frame is fixed at 16:10 and both layers fill it, so mismatched sizes will crop to that box.

Skip it when the person must choose among several unrelated pictures. That is Image results. Skip it when they still need to mark the region to change. That is Edit region, which adds a brush and a prompt instead of a divider. Image generation is the wait before either picture exists. If the only goal is a side-by-side pair with no overlap, put the two images in a row. This control is specifically the overlapping wipe.

Can the two sides be real images?

Yes. before and after are nodes you render, not seeds. The preview happens to draw SVG landscapes, one grey and one warm, so the split is visible with no assets. Pass img elements, canvases, or any other node that fills the frame. The component never reads their pixels.

How far do the arrow keys move the line?

Two percent per arrow, ten with Shift, twenty-five with Page Up or Page Down, and Home or End for the two edges. The handle reports the rounded percent as its slider value. Dragging the frame, not only the handle, also moves it, because the pointer handlers sit on the whole picture.