Before / After
ComponentsBefore / After
CardsNew

Before / After

Two points of view, one surface. Pull a fine line between what was and what could be.

React + CSS
Live component. Go ahead, interact.
01

Installation

Run this in your shadcn-configured React project. The component and stylesheet are added together.

TERMINAL
npx shadcn@latest add http://localhost:5173/r/before-after.json

This command uses the current site address. For localhost, keep this preview running on the same computer. Files follow your configured components alias.

02

Usage

Import the component and make the details your own.

TypeScript
import { BeforeAfter } from '@/components/anticraft/BeforeAfter';

export function Example() {
  return (
    <BeforeAfter
      beforeLabel="First thought"
      afterLabel="Fresh perspective"
      defaultValue={50}
      before={<div style={{ display: 'grid', placeItems: 'center', background: '#c6c5b9', color: '#363a33', fontSize: 58 }}>Aa</div>}
      after={<div style={{ display: 'grid', placeItems: 'center', background: '#e9a577', color: '#59352a', fontFamily: 'Georgia, serif', fontStyle: 'italic', fontSize: 72 }}>Aa</div>}
    />
  );
}
03

Props

PropTypeDefaultDescription
beforeReactNodeRequiredDecorative artwork for the left reveal layer. Images fill the surface using object-fit: cover. Keep faces free of controls and provide meaningful descriptions in the labels or surrounding text.
afterReactNodeRequiredDecorative artwork beneath the reveal. Both faces stay full size as the dividing line moves; their content is hidden from assistive technology and made inert.
beforeLabelstring'Before'The visible label for the left layer. It is also used in the slider’s accessible name and value.
afterLabelstring'After'The visible label for the right layer. It is also used in the slider’s accessible name and value.
defaultValuenumber50The initial percentage of the before layer revealed, rounded and clamped from 0 to 100. Non-finite values fall back to 50.
onValueChange(value: number) => voidundefinedCalled when the native slider changes the reveal percentage. Use a client component when providing this callback.
classNamestring''Additional classes. Set --ac-compare-height to change the default 300px height; paper, ink, and focus tokens customize the frame.
04

Motion & accessibility

Considered by default.

Drag the handle along the middle of the artwork or focus the native range and use arrow keys, Home, or End. The 44px horizontal interaction strip preserves vertical touch scrolling. The divider follows the value directly, with no automatic animation or easing. The slider exposes both labels and the current percentage; the visual output does not announce every drag movement.

Use semantic content and meaningful labels in your composition. Check contrast and keyboard behavior with your own styles and content.