Skip to content
Template Empire / components

Search components

10 results

Browse components

Before After Slider

A free before after slider: an image and media component that wipes between two pictures with React, Motion and Tailwind.

  • Automated axe check
  • Reduced-motion tested
  • SSR build verified
  • Motion
  • 1 runtime package

Before After Slider is a free before after slider component for Next.js and React, built with Motion and styled with Tailwind. It stacks two images and reveals the second from the left with a bounded clip-path as you drag the divider, so you can compare an edit, a renovation or a design change in place.

A single transparent native range input owns every interaction and all slider semantics, which keeps it fully keyboard operable and screen-reader friendly out of the box. Pointer and touch dragging move the divider through a Motion value with no React render per sample, the handle springs to a larger size while you drag, and with prefers-reduced-motion enabled the divider still moves but does so instantly with no easing or spring.

Mountain valley at dusk in cool, muted tonesThe same mountain valley in bright, saturated daylight

Drag the handle, or focus it and use the arrow keys, to wipe between the two versions. Shift plus an arrow jumps in bigger steps and Home or End snaps to either edge.

Customise

Component settings update the preview and generated code together.

Content

Appearance

Behaviour

50%

Install

Add the @te registry to your components.json once:

{
  "registries": {
    "@te": "https://templateempire.io/r/{name}.json"
  }
}

Then install the component:

npx shadcn@latest add @te/media-before-after

Usage

import { MediaBeforeAfter } from "@/components/media-before-after";

export function Example() {
  return (
    <MediaBeforeAfter
      before={{ src: "/before.jpg", alt: "Room before the renovation" }}
      after={{ src: "/after.jpg", alt: "Room after the renovation" }}
      initial={50}
      aspectRatio={16 / 9}
      label="Renovation comparison"
    />
  );
}

Props

PropTypeDefaultDescription
before{ src: string; alt: string }requiredBase image shown underneath and revealed to the right of the divider. Its alt text stays in the accessibility tree.
after{ src: string; alt: string }requiredImage revealed from the left as the divider moves right. Its alt text stays in the accessibility tree.
initialnumber50Starting divider position as a percentage, clamped to 0 to 100.
aspectRationumber16 / 9Positive width divided by height ratio used to reserve layout space so there is no layout shift.
labelstring"Comparison slider"Accessible name for the native range control.
classNamestringundefinedAdditional classes merged onto the wrapper.

Customisation

Before After Slider declares no tokens of its own; the divider line and handle draw from the shared foreground, background and ring tokens so they invert with the theme, and the keyboard easing mirrors the --dur-1 and --ease-out-quart motion tokens. Reserve a different shape with the aspectRatio prop and restyle the frame from the className prop with the same semantic tokens the rest of the library uses:

<MediaBeforeAfter
  before={{ src: "/before.jpg", alt: "Studio shot, unedited" }}
  after={{ src: "/after.jpg", alt: "Studio shot, colour graded" }}
  aspectRatio={4 / 3}
  className="rounded-3xl border-2"
/>

Frequently asked questions

Is Before After Slider free for commercial use?
Yes. Before After Slider is MIT licensed, so you can use it in personal and commercial projects without attribution.
Is the before after slider accessible and keyboard operable?
Yes. A single native range input owns the slider role, accessible name, minimum, maximum and current value, so screen readers announce it correctly and it never uses a fake role on a button. Arrow keys move the divider by 2 percent, Shift plus an arrow moves 10 percent, and Home and End snap to either edge, all clamped to the 0 to 100 range. The visible handle shows a focus ring driven from the range focus state, and with prefers-reduced-motion enabled every change still works but happens instantly.
Will dragging the slider hurt performance or cause layout shift?
No. The wrapper reserves its space from the aspectRatio prop so cumulative layout shift stays at zero, and dragging updates a Motion value directly with no React render per pointer sample. The divider only ever animates a transform and the revealed image uses a clip-path bounded to the media box, so no layout property is animated and no will-change is left behind once you stop.

Related components

More free image and media are on the way. Browse the full component library in the meantime.

Want the full page this belongs to?Template Empire builds complete Next.js templates with this motion system throughout. Browse the paid templates that pair with these free components.Explore Template Empire templates