Before After
An accessible before/after comparison component with a draggable slider.
Basic Usage
Custom Initial Position
Start the slider at a different position by setting the value prop.
Vertical Orientation
With x-model
Position: %
Disabled State
API Reference
Component Props
| Prop | Type | Default | Description |
|---|---|---|---|
value | number | 50 | Position of the divider as a percentage (0 to 100) |
orientation | 'horizontal' | 'vertical' | 'horizontal' | Orientation of the comparison slider |
disabled | boolean | false | Whether the slider is disabled |
step | number | 1 | Keyboard step increment |
Parts
| Part | Description |
|---|---|
x-before-after | Root container element |
x-before-after:before | Container for the "before" image (clipped based on position) |
x-before-after:after | Container for the "after" image (clipped inversely) |
x-before-after:separator | Visual divider line at the current position |
x-before-after:handle | Draggable thumb element for controlling the position |
Data Attributes
| Attribute | Description |
|---|---|
data-orientation | Current orientation (horizontal or vertical) |
data-disabled | Present when the slider is disabled |
data-dragging | Present while the handle is being dragged |
Events
| Event | Detail | Description |
|---|---|---|
change | { value } | Fired when the slider position changes |
Keyboard Interactions
| Key | Description |
|---|---|
ArrowRight / ArrowUp | Increase position by step |
ArrowLeft / ArrowDown | Decrease position by step |
PageUp | Increase position by 10x step |
PageDown | Decrease position by 10x step |
Home | Set position to 0% |
End | Set position to 100% |
Accessibility
This component follows the WAI-ARIA Slider Pattern:
- Uses
role="slider"on the handle element - Provides
aria-valuenow,aria-valuemin,aria-valuemaxattributes - Supports
aria-orientationfor vertical mode - Provides
aria-valuetextfor human-readable announcements - Implements all required keyboard interactions
- Add an
aria-labelon the handle for context-specific descriptions (e.g.,aria-label="Photo brightness comparison") - Include descriptive
alttext on both images for screen readers
Styling
The component is completely unstyled by default. Use the data attributes and parts to style it:
css
/* Root container */
[data-scope="before-after"][data-part="root"] {
/* Container styles, set dimensions here */
}
/* Separator line */
[data-part="separator"] {
/* Divider line styles */
}
/* Handle */
[data-part="handle"] {
/* Thumb/handle styles */
}
/* Dragging state */
[data-dragging] [data-part="handle"] {
/* Styles while actively dragging */
}
/* Disabled state */
[data-disabled] {
/* Disabled appearance */
}Tips
- Both
beforeandaftercontainers should hold full-size content. The component clips them usingclip-path. - Set explicit dimensions on the root element (e.g.,
aspect-video, fixed height/width) so both images align correctly. - Use
object-coveron images to prevent distortion when aspect ratios differ. - The
beforeandafterparts can contain any content, not just images. - Add labels (e.g., "Before" / "After" badges) outside the clipped containers so they remain visible at all positions.