Skip to content

Before After

An accessible before/after comparison component with a draggable slider.

Basic Usage

Before
After
BeforeAfter

Custom Initial Position

Start the slider at a different position by setting the value prop.

Before
After

Vertical Orientation

Before
After
BeforeAfter

With x-model

Before
After

Position: %

Disabled State

Before
After

API Reference

Component Props

PropTypeDefaultDescription
valuenumber50Position of the divider as a percentage (0 to 100)
orientation'horizontal' | 'vertical''horizontal'Orientation of the comparison slider
disabledbooleanfalseWhether the slider is disabled
stepnumber1Keyboard step increment

Parts

PartDescription
x-before-afterRoot container element
x-before-after:beforeContainer for the "before" image (clipped based on position)
x-before-after:afterContainer for the "after" image (clipped inversely)
x-before-after:separatorVisual divider line at the current position
x-before-after:handleDraggable thumb element for controlling the position

Data Attributes

AttributeDescription
data-orientationCurrent orientation (horizontal or vertical)
data-disabledPresent when the slider is disabled
data-draggingPresent while the handle is being dragged

Events

EventDetailDescription
change{ value }Fired when the slider position changes

Keyboard Interactions

KeyDescription
ArrowRight / ArrowUpIncrease position by step
ArrowLeft / ArrowDownDecrease position by step
PageUpIncrease position by 10x step
PageDownDecrease position by 10x step
HomeSet position to 0%
EndSet 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-valuemax attributes
  • Supports aria-orientation for vertical mode
  • Provides aria-valuetext for human-readable announcements
  • Implements all required keyboard interactions
  • Add an aria-label on the handle for context-specific descriptions (e.g., aria-label="Photo brightness comparison")
  • Include descriptive alt text 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 before and after containers should hold full-size content. The component clips them using clip-path.
  • Set explicit dimensions on the root element (e.g., aspect-video, fixed height/width) so both images align correctly.
  • Use object-cover on images to prevent distortion when aspect ratios differ.
  • The before and after parts 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.

Built with Alpine.js and inspired by Zag.js