MKT UI
Sections

Before and after

Two images compared with a slider that works from the keyboard.

Open preview (opens in a new tab)

Installation

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

MKT UI is not published yet, so this points at your local development server. Set NEXT_PUBLIC_REGISTRY_URL to the deployed origin to show the public command.

Usage

"use client";

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

<BeforeAfter
  before={{ src: "/jobs/12-before.jpg", alt: "Corroded copper pipework under the sink", label: "Before" }}
  after={{ src: "/jobs/12-after.jpg", alt: "The same run replaced in PEX with new shut-off valves", label: "After" }}
  caption="Kitchen repipe, Crestview. Two days on site."
/>

Props

PropTypeDefaultDescription
before (required)BeforeAfterImage—`{ src, alt, label? }`. The alt text describes the before state on its own.
after (required)BeforeAfterImage—`{ src, alt, label? }`. The alt text describes the after state on its own.
defaultPositionnumber50Starting split, 0–100.
controlLabelstring"Reveal the before image"Accessible name for the slider.
aspect"video" | "square" | "wide" | "portrait""video"Frame ratio. Reserves space before the images load.
captionReactNode—Caption under the frame.

Accessibility

This is the section where a hand-rolled implementation usually goes wrong, so the design is deliberate:

The control is a real <input type="range">. That single decision provides keyboard operation, a focus ring, and a value announcement for free. A custom pointer handler would need all three rebuilt, and in practice ships without them — leaving the comparison unusable for anyone without a mouse.

aria-valuetext says "70% before, 30% after" rather than a bare "70". The number alone does not say what it is a number of.

Both images are always in the DOM with their own alt text. Someone who cannot see either one still gets both descriptions, which is the actual content of the section.

Arrow keys move the split by 1%, Home and End jump to either end.

Writing the alt text

Describe each state independently, as if the other image did not exist. "Before" and "After" are the labels, not the descriptions.

PoorBetter
alt="Before"alt="Corroded copper pipework under the sink"
alt="After photo"alt="The same run replaced in PEX with new shut-off valves"

Limitations

  • Client component — it ships JavaScript.
  • Horizontal split only. No vertical wipe or fade.
  • Both images must share an aspect ratio, or the comparison misleads.
  • No gallery of multiple comparisons yet.

On this page