Animate Elements On Scroll With Parallax Effect – locomotive-scroll
Version 5 represents a complete rewrite from previous versions. The library now uses dual Intersection Observer strategies to optimize performance. Simple viewport triggers use one observer while continuous animations like parallax use a separate RAF-based observer.
This separation reduces unnecessary computation. locomotive-scroll automatically disables parallax on touch devices to preserve native scrolling performance. Custom scroll containers are now supported alongside the default full-page scrolling mode.
1. Install the package and import the LocomotiveScroll module.
# NPM $ npm install locomotive-scroll --save
import LocomotiveScroll from 'locomotive-scroll'; @import 'locomotive-scroll/dist/locomotive-scroll.css';
2. Or load the necessary JavaScript & CSS files from the bundled folder.
<script src="bundled/locomotive-scroll.min.js"></script> <link href="bundled/locomotive-scroll.css" rel="stylesheet" />
3. Initialize the LocomotiveScroll with default settings.
const myScroll = new LocomotiveScroll();
4. Apply the LocomotiveScroll to target elements using the data-scroll attribute:
<div data-scroll>Element To Animate</div>
5. Config the parallax scroll effect with the following data attributes:
data-scroll: Enable viewport detection and scroll observation on the element. Required for all scroll-based features.data-scroll-speed (number): Set parallax speed relative to scroll container size. Positive values move slower than scroll. Negative values reverse direction. Example: 0.5 moves at half scroll speed. Automatically disabled on touch devices unless data-scroll-enable-touch-speed is present.data-scroll-position (string): Define trigger positions for viewport detection. Format: 'element_position, viewport_position'. Values: 'start', 'middle', 'end'. Example: 'start, middle' triggers when element’s top edge reaches viewport center. Default: 'start, end'.data-scroll-offset (string): Add pixel or percentage offset to trigger points. Format: 'enter_offset, leave_offset'. Example: '200, 100' triggers 200px before entry and 100px before exit. Percentages are relative to viewport height. Default: '0, 0'.data-scroll-class (string): Class name to apply when element is in viewport. Default: 'is-inview'.data-scroll-repeat: Allow class and events to retrigger on each viewport entry. Without this attribute, triggers fire only once.data-scroll-call (string): Custom event name to dispatch when element enters or leaves viewport. Listen with window.addEventListener(eventName, handler).data-scroll-css-progress: Add --progress CSS custom property to the element. Value ranges from 0 to 1 as element moves through viewport.data-scroll-event-progress (string): Custom event name for progress updates. Fires continuously with progress value in event.detail.data-scroll-to: Convert element into a scroll trigger. Uses href attribute for links or data-scroll-to-href for other elements. Prevents default click behavior.data-scroll-to-href (string): Target selector or position for data-scroll-to action. Example: '#section-3'.data-scroll-to-offset (number): Scroll padding top in pixels for data-scroll-to action. Example: 100 adds 100px offset from target.data-scroll-to-duration (number): Animation duration in seconds for data-scroll-to action. Example: 2 creates a 2-second scroll animation.data-scroll-ignore-fold: Prevent automatic offset adjustment for elements visible in the initial viewport. By default, in-fold elements start their progress from their initial position.data-scroll-enable-touch-speed: Override the automatic parallax disabling on touch devices. Enables data-scroll-speed on mobile and tablets. Use carefully as this may impact scroll performance.<div data-scroll
data-scroll-speed="1">
data-scroll-call="EVENT_NAME"
>
Element To Animate
</div> 6. All possible settings to config the library.
lenisOptions (object): Configures the underlying Lenis instance. wrapper (HTMLElement|Window): The scroll container. Defaults to window.content (HTMLElement): The content element. Defaults to document.documentElement.lerp (number): Linear interpolation intensity (0 to 1). Defaults to 0.1.duration (number): Animation duration.orientation (string): ‘vertical’ or ‘horizontal’.gestureOrientation (string): ‘vertical’, ‘horizontal’, or ‘both’.smoothWheel (boolean): Enables smooth scrolling for mouse wheel. Defaults to true.smoothTouch (boolean): Enables smooth scrolling for touch. Defaults to false.wheelMultiplier (number): Multiplier for mouse wheel events.touchMultiplier (number): Multiplier for touch events.normalizeWheel (boolean): Normalizes wheel inputs across browsers.easing (function): Custom easing function.triggerRootMargin (string): Root margin for IntersectionObserver triggers. Defaults to '-1px -1px -1px -1px'.rafRootMargin (string): Root margin for RAF-based updates. Defaults to '100% 100% 100% 100%'.autoStart (boolean): Starts the RAF loop automatically. Defaults to true.scrollCallback (function): Callback returning scroll object { scroll, limit, velocity, direction, progress }.initCustomTicker (function): Callback to initialize an external ticker (like GSAP).destroyCustomTicker (function): Callback to destroy the external ticker.const myScroll = new LocomotiveScroll({
lenisOptions: {
// ...
},
// more options here
}); 7. API methods.
// Stop the scroll animation loop
// Useful when pausing scroll interactions during modals or overlays
myScroll.stop();
// Resume the scroll animation loop
// Call after stopping to re-enable scroll
myScroll.start();
// Manually trigger resize recalculation
// Rarely needed since Lenis handles ResizeObserver internally
myScroll.resize();
// Destroy the Locomotive Scroll instance and remove all event listeners
// Call when unmounting components or cleaning up instances
myScroll.destroy();
// Scroll to a target element, position, or keyword
// target: HTMLElement, number (position), or string ('top', 'bottom', CSS selector)
// options: object with offset, duration, easing, immediate, lock, force, onComplete
myScroll.scrollTo(target, options);
// Add scroll observation to newly inserted DOM elements
// newContainer: HTMLElement containing new [data-scroll] elements
myScroll.addScrollElements(newContainer);
// Remove scroll observation from DOM elements about to be removed
// oldContainer: HTMLElement containing [data-scroll] elements to unobserve
myScroll.removeScrollElements(oldContainer); 8. Event handlers.
// Fired on each scroll frame when scrollCallback is configured
// Provides scroll position, velocity, direction, and progress data
scroll = new LocomotiveScroll({
scrollCallback: ({ scroll, limit, velocity, direction, progress }) => {
console.log('Scroll data:', { scroll, limit, velocity, direction, progress });
}
});
// Custom viewport trigger event (configured via data-scroll-call attribute)
// Fired when element enters or leaves viewport
window.addEventListener('yourCustomEvent', (e) => {
const { target, way, from } = e.detail;
// target: the element that triggered the event
// way: 'enter' or 'leave'
// from: 'start' or 'end' (which edge triggered)
console.log(`Element ${way} viewport from ${from}`);
});
// Custom progress event (configured via data-scroll-event-progress attribute)
// Fired continuously as element moves through viewport
window.addEventListener('yourProgressEvent', (e) => {
const { target, progress } = e.detail;
// progress: 0 to 1 representing element's position in viewport
console.log(`Element progress: ${progress}`);
}); Q: Does it work on mobile devices?
A: Yes. However, the library automatically disables the parallax effect (data-scroll-speed) on touch devices. This preserves the native scroll feel and performance. You can force it on by adding the data-scroll-enable-touch-speed attribute.
Q: Can I use it with React or Vue?
A: Yes. You should initialize the instance inside a useEffect (React) or onMounted (Vue) hook. Remember to call .destroy() in the cleanup function to prevent memory leaks.
Q: How do I handle dynamic content loaded via AJAX?
A: You must tell the instance about the new content. Use the addScrollElements($container) method after the new DOM elements are injected.
Q: Why isn’t my fixed header working?
A: Version 5 supports position: fixed natively because it no longer uses a transform wrapper for the whole page. If you use a custom container, verify your CSS context.
v5.0.1 (01/15/2026)
v4.1.4 (05/03/2022)
v4.1.3 (10/21/2021)
v4.1.0 (02/19/2021)
v4.0.3 (11/17/2020)
v4.0.1 (11/16/2020)
v3.6.1 (10/15/2020)
v3.5.0 (05/28/2020)
v3.1.8 (11/30/2019)
The post Animate Elements On Scroll With Parallax Effect – locomotive-scroll appeared first on CSS Script.
A cleverly crafted fake Zoom website has silently pushed surveillance software onto Windows machines, infecting…
A newly uncovered cloaking platform called 1Campaign is giving cybercriminals a powerful tool to push malicious advertisements…
Apple iPhone users, check out this new deal on an ultra-slim MagSafe power bank that…
IGN Live is back for another year, this year taking place June 6-7 in downtown…
One Piece Season 2 arrives on Netflix on March 10 at 12:00am PDT, and IGN…
In January, Qualcomm hinted to The Verge that it might finally bring its powerful Arm-based…
This website uses cookies.