Draggable Image Track Parallax
See the Pen Draggable Image Track Parallax.
Tech & Dependencies
Features
- ✓ Drag and Drop
- ✓ Internal Parallax
- ✓ Web Animations API
- ✓ Touch Support
Browser Support
Core
This is a Draggable Image Track Parallax component. It replaces standard scrollbars with a custom, click-and-drag horizontal interface. Its function is to provide a highly kinetic, app-like browsing experience for image galleries, featuring an internal parallax effect where the images pan slightly inside their frames as the entire track moves.
Specs
- Weight: ~2 KB. Zero external dependencies.
- Performance: High. It utilizes the Web Animations API (
element.animate()) to interpolate thetransformandobject-positionproperties, offloading the heavy lifting to the browser’s compositor thread. - Theming / Customization: Minimalist. The track relies on
vh/vwandvminunits, making the CSS highly scalable. Images are constrained byobject-fit: cover. - Responsiveness: Fluid. Calculates drag distances as a percentage of
window.innerWidth, ensuring the drag sensitivity feels consistent across mobile and desktop screens. - Web APIs: Web Animations API, Touch Events API (for mobile support).
- Graceful Degradation: [!] High risk. If JavaScript is disabled, the gallery is completely locked in place and inaccessible. It lacks a native horizontal scroll fallback.
Anatomy
The structure separates the moving track from the fixed viewport.
- HTML (The Skeleton): A singular
#image_trackcontainer that holds a series of<img>tags. Data attributes (data-mouse-down-at,data-prev-percentage) are used natively in the DOM to store interaction state. - CSS (The Skin): Sets
overflow: hiddenon the body to disable native scrolling. Images are set toobject-fit: coverand heavily rely onobject-positionfor the internal parallax effect. - JS (The Nervous System): A unified event listener system that captures both mouse and touch events (
onmousedown/ontouchstart). The logic calculates the delta of the drag and translates that into a percentage-based transform.
Logic
The standout feature is the Coupled Internal Parallax.
// 1. Move the entire track
track.animate({
transform: `translate(${nextPercentage}%, -50%)`
}, { duration: 3000, fill: "forwards" });
// 2. Move the image INSIDE its frame simultaneously
for (const image of track.getElementsByClassName("image")) {
image.animate({
objectPosition: `${100 + nextPercentage}% center`
}, { duration: 3000, fill: "forwards" });
}
As the user drags, the code doesn’t just slide the #image_track container horizontally. It simultaneously animates the object-position of every image inside that container. Because nextPercentage ranges from 0 to -100, the objectPosition shifts from 100% (right-aligned) to 0% (left-aligned). This means that as the track moves left, the images slowly pan to the right within their own borders, creating a striking 3D “window” effect without requiring multiple complex layers or absolute positioning.
Feel
Viscous and cinematic. The 3000ms duration in the .animate() call creates a heavy, lingering momentum. The track doesn’t snap to a halt when you release the mouse; it glides to a stop like a heavy physical object sliding on ice. The internal parallax makes the flat photographs feel like deep portals, adding a premium, editorial quality to the simple act of browsing.


