Comparison
Import
Section titled “Import”import { Comparison } from '@delightstack/components';Basic Usage
Section titled “Basic Usage”View code
<script> import { Comparison } from '@delightstack/components';</script>
<Comparison before="/images/photo-original.jpg" after="/images/photo-edited.jpg" label_before="Photo A" label_after="Photo B" snaps={[50]}/>Examples
Section titled “Examples”With Alt Text
Section titled “With Alt Text”View code
<Comparison before="/images/photo-original.jpg" after="/images/photo-edited.jpg" before_alt="Original photo" after_alt="Edited photo with filters applied"/>Custom Labels
Section titled “Custom Labels”View code
<Comparison before="/images/design-v1.png" after="/images/design-v2.png" label_before="Version 1" label_after="Version 2"/>Without Labels
Section titled “Without Labels”View code
<Comparison before="/images/before.jpg" after="/images/after.jpg" show_labels={false}/>Vertical Orientation
Section titled “Vertical Orientation”The divider moves up and down instead of left and right.
View code
<Comparison before="/images/before.jpg" after="/images/after.jpg" vertical/>Controlled Position
Section titled “Controlled Position”Bind to the position prop to control or read the slider position (0-100).
Position: 50%
View code
<script> let position = $state(50);</script>
<Comparison before="/images/before.jpg" after="/images/after.jpg" bind:position/>
<p>Position: {position}%</p>Snap Points
Section titled “Snap Points”Define snap points that the divider magnetically locks to. The divider uses springy magnetic gravity near snap points and a rubber-band effect when dragged past the edges.
Position: 50%
View code
<Comparison before="/images/before.jpg" after="/images/after.jpg" snaps={[25, 50, 75]}/>Skeleton Loading
Section titled “Skeleton Loading”View code
<Comparison skeleton={loading} before={before_url} after={after_url} />| Prop | Type | Default | Description |
|---|---|---|---|
before | string | required | Before image URL |
after | string | required | After image URL |
before_alt | string | 'Before' | Before image alt text |
after_alt | string | 'After' | After image alt text |
position | number | 50 | Divider position (0-100), bindable |
vertical | boolean | false | Vertical orientation (divider moves up/down) |
show_labels | boolean | true | Show before/after labels |
label_before | string | 'Before' | Before label text |
label_after | string | 'After' | After label text |
skeleton | boolean | false | Show loading skeleton |
snaps | number[] | [] | Snap points the divider magnetically locks to (0-100) |
id | string | auto | Element ID |
class | string | '' | Additional CSS classes |
Events
Section titled “Events”| Event | Detail | Description |
|---|---|---|
onchange | { position: number } | Fired when the divider position changes |
CSS Variables
Section titled “CSS Variables”| Variable | Default | Description |
|---|---|---|
--cmp-radius | var(--radius-xl, 20px) | Corner radius of the container (set 0 to square it off) |
--cmp-aspect | 16 / 9 | Aspect ratio of the skeleton placeholder — set it to match the real images so the skeleton ↔ loaded swap doesn’t shift |
Accessibility
Section titled “Accessibility”- Divider handle has
role="slider"witharia-valuenow,aria-valuemin="0", andaria-valuemax="100" aria-label="Comparison slider"on the handle- Both images have descriptive alt text
- Full keyboard support:
- Tab to focus the handle
- Arrow Left/Right (horizontal) or Arrow Up/Down (vertical) moves in 1% increments
- Shift+Arrow moves in 10% increments
- Home moves to 0%
- End moves to 100%
- Click anywhere on the image to jump the divider to that position
touch-action: noneprevents scroll interference on mobile- Images have
draggable="false"to prevent native drag behavior