compare-surface

Before/after image comparison slider with drag handle, keyboard support, and progressive enhancement.

Overview

The <compare-surface> component creates a before/after comparison slider. Two children overlay each other, and a draggable divider reveals one side. Works with any two children — images, divs, or any other elements.

Attributes

Attribute Type Default Description
position number 50 Initial slider position from 0 (fully left) to 100 (fully right).

Custom Start Position

Set position to control where the divider starts. A value of 25 means the divider starts 25% from the left, showing mostly the “after” content.

Before
After

Non-Image Content

The component works with any two child elements, not just images. Use divs, text blocks, or any HTML content.

Draft

The original version before revisions.

Final

The polished version with improved clarity.

Keyboard Navigation

Key Action
ArrowLeft / ArrowDown Move divider 1% left
ArrowRight / ArrowUp Move divider 1% right
Shift + Arrow Move divider 10% in the arrow direction

Events

Event Detail Description
compare-surface:change { position: number } Fired when the slider position changes (drag or keyboard).

Accessibility

Slider Role

The divider has role="slider" with aria-valuemin, aria-valuemax, and aria-valuenow. Screen readers announce position changes as the slider moves.

Keyboard Support

The divider is focusable (tabindex="0") and responds to arrow keys. Shift + arrow provides larger steps for faster navigation.

Touch Support

The divider uses touch-action: none and setPointerCapture for reliable touch/pointer drag behavior across devices.

Styling

The divider and handle can be styled with CSS. The divider is a .comparison-divider element with a ::after pseudo-element for the circular handle.

Progressive Enhancement

Without JavaScript, both children display side-by-side in a natural grid. The :not(:defined) selector provides the fallback layout. Once JS registers the component, children overlap and the clip-path slider takes over.

Related