locomotive-scroll
🛤 Detection of elements in viewport & smooth scrolling with parallax.
Top Related Projects
Simple & lightweight (<4kb gzipped) vanilla JavaScript library to create smooth & beautiful animations when you scroll.
The javascript library for magical scroll interactions.
Animate on scroll library
🚀 Performance focused, lightweight scroll animation library 🚀
Most modern mobile touch slider with hardware accelerated transitions
Quick Overview
Locomotive Scroll is a smooth scrolling library for modern websites. It provides a customizable and performant way to implement smooth scrolling effects, parallax animations, and scroll-based interactions in web applications.
Pros
- Smooth and performant scrolling experience
- Customizable with various options and callbacks
- Supports both vertical and horizontal scrolling
- Easy integration with modern JavaScript frameworks
Cons
- May have a learning curve for developers new to scroll-based animations
- Can potentially impact performance on low-end devices if not optimized properly
- Limited browser support for older versions (IE11 and below)
- Requires additional setup for server-side rendering environments
Code Examples
- Basic initialization:
import LocomotiveScroll from 'locomotive-scroll';
const scroll = new LocomotiveScroll({
el: document.querySelector('[data-scroll-container]'),
smooth: true
});
- Adding parallax effect:
<div data-scroll-section>
<img data-scroll data-scroll-speed="2" src="image.jpg" alt="Parallax Image">
</div>
- Triggering a callback on scroll:
scroll.on('scroll', (args) => {
console.log('Scroll position:', args.scroll.y);
});
- Programmatically scrolling to an element:
scroll.scrollTo('#target-element');
Getting Started
- Install the package:
npm install locomotive-scroll
- Import and initialize in your JavaScript file:
import LocomotiveScroll from 'locomotive-scroll';
const scroll = new LocomotiveScroll({
el: document.querySelector('[data-scroll-container]'),
smooth: true,
multiplier: 1,
class: 'is-inview',
});
- Add the necessary HTML attributes to your markup:
<div data-scroll-container>
<section data-scroll-section>
<h1 data-scroll>Hello, Locomotive Scroll!</h1>
</section>
</div>
- Include the CSS file in your project:
<link rel="stylesheet" href="node_modules/locomotive-scroll/dist/locomotive-scroll.css">
Competitor Comparisons
Simple & lightweight (<4kb gzipped) vanilla JavaScript library to create smooth & beautiful animations when you scroll.
Pros of lax.js
- Lightweight and simple to use, with a smaller learning curve
- Offers a wide range of pre-built animations and effects
- Supports both scroll-based and time-based animations
Cons of lax.js
- Less customizable for complex scroll-based interactions
- May require more manual setup for advanced parallax effects
- Limited built-in support for horizontal scrolling
Code Comparison
lax.js:
lax.init()
lax.addDriver('scrollY', function() {
return window.scrollY
})
lax.addElements('.selector', {
scrollY: {
translateY: [
["elInY", "elOutY"],
[0, 100],
],
}
})
Locomotive Scroll:
const scroll = new LocomotiveScroll({
el: document.querySelector('[data-scroll-container]'),
smooth: true,
multiplier: 1,
})
scroll.on('scroll', (instance) => {
// Custom scroll handling
})
Both libraries offer smooth scrolling and parallax effects, but Locomotive Scroll provides more advanced features for custom scroll behaviors and complex animations. lax.js is easier to set up for simple effects, while Locomotive Scroll offers greater control and flexibility for larger projects.
The javascript library for magical scroll interactions.
Pros of ScrollMagic
- More mature and established library with a larger community
- Offers a wider range of animation and scrolling effects
- Provides better documentation and examples
Cons of ScrollMagic
- Heavier in terms of file size and performance impact
- Less modern approach to smooth scrolling
- Requires more setup and configuration for basic use cases
Code Comparison
ScrollMagic:
var controller = new ScrollMagic.Controller();
var scene = new ScrollMagic.Scene({
triggerElement: "#trigger",
duration: 300
})
.setTween("#animate", {scale: 2.5})
.addTo(controller);
Locomotive Scroll:
const scroll = new LocomotiveScroll({
el: document.querySelector('[data-scroll-container]'),
smooth: true
});
scroll.on('scroll', (obj) => {
// Handle scroll event
});
ScrollMagic focuses on creating scroll-based animations and scenes, while Locomotive Scroll emphasizes smooth scrolling with simpler implementation. ScrollMagic requires more setup but offers more complex animation possibilities. Locomotive Scroll provides a more modern and performant approach to smooth scrolling with less code, making it easier to implement basic scroll-based interactions.
Animate on scroll library
Pros of AOS
- Lightweight and easy to implement with minimal setup
- Supports a wide range of animation effects out of the box
- Works well with responsive designs and various screen sizes
Cons of AOS
- Limited customization options for advanced animations
- May not perform as smoothly on complex, long-scrolling pages
- Lacks advanced features like parallax effects or horizontal scrolling
Code Comparison
AOS:
AOS.init({
duration: 1000,
easing: 'ease-in-out',
once: true
});
Locomotive Scroll:
const scroll = new LocomotiveScroll({
el: document.querySelector('[data-scroll-container]'),
smooth: true,
multiplier: 1.0
});
AOS focuses on simple, declarative animations triggered by scrolling, while Locomotive Scroll provides a more comprehensive scrolling experience with advanced features like smooth scrolling and parallax effects. AOS is easier to implement for basic scroll animations, but Locomotive Scroll offers more control and customization for complex scrolling interactions. The choice between the two depends on the project's specific requirements and the desired level of scrolling sophistication.
🚀 Performance focused, lightweight scroll animation library 🚀
Pros of Sal
- Lightweight and simple to use, with minimal configuration required
- Supports a wide range of animation effects out of the box
- Easy integration with existing projects due to its data-attribute-based approach
Cons of Sal
- Less advanced features compared to Locomotive Scroll
- Limited customization options for complex scroll-based animations
- May not perform as well for large-scale, performance-critical applications
Code Comparison
Sal:
sal({
threshold: 0.5,
once: false,
});
Locomotive Scroll:
const scroll = new LocomotiveScroll({
el: document.querySelector('[data-scroll-container]'),
smooth: true,
multiplier: 1,
});
Key Differences
- Sal focuses on simple scroll-based animations, while Locomotive Scroll offers more advanced scrolling features
- Locomotive Scroll provides smoother scrolling experiences and better performance for complex layouts
- Sal uses a simpler API and data attributes, making it easier to implement for basic use cases
- Locomotive Scroll offers more granular control over scrolling behavior and animations
Use Cases
- Choose Sal for quick implementation of basic scroll animations in smaller projects
- Opt for Locomotive Scroll when building complex, high-performance websites with advanced scrolling requirements
Most modern mobile touch slider with hardware accelerated transitions
Pros of Swiper
- More versatile, supporting various types of sliders and carousels
- Larger community and ecosystem, with more plugins and extensions
- Better suited for touch-enabled devices and mobile-first design
Cons of Swiper
- Can be more complex to set up and customize for simple scrolling effects
- May have a larger file size and performance overhead for basic use cases
- Less focused on smooth scrolling animations compared to Locomotive Scroll
Code Comparison
Locomotive Scroll basic setup:
import LocomotiveScroll from 'locomotive-scroll';
const scroll = new LocomotiveScroll({
el: document.querySelector('[data-scroll-container]'),
smooth: true
});
Swiper basic setup:
import Swiper from 'swiper';
const swiper = new Swiper('.swiper-container', {
slidesPerView: 1,
spaceBetween: 10,
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
},
});
While both libraries offer smooth scrolling capabilities, Locomotive Scroll is more focused on creating custom scroll experiences, whereas Swiper excels in creating interactive sliders and carousels. Locomotive Scroll provides a simpler API for smooth scrolling, while Swiper offers more options for slide-based content navigation.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
ð Locomotive Scroll v5 Beta Release
Try out the beta version of Locomotive Scroll v5!
ð Click here to try Locomotive Scroll v5 Beta
Your feedback is valuable during this beta testing phase. If you encounter any issues or have suggestions, please open an issue.
Happy scrolling! ð
Locomotive Scroll
Detection of elements in viewport & smooth scrolling with parallax effects.
Installation
â ï¸ Scroll-hijacking is a controversial practice that can cause usability, accessibility, and performance issues. Please use responsibly.
npm install locomotive-scroll
Usage
Basic
With simple detection.
HTML
<h1 data-scroll>Hey</h1>
<p data-scroll>ð</p>
CSS
Add the base styles to your CSS file.
JS
With a bundler
import LocomotiveScroll from 'locomotive-scroll';
const scroll = new LocomotiveScroll();
Or without
<script src="locomotive-scroll.min.js"></script>
<script>
(function () {
var scroll = new LocomotiveScroll();
})();
</script>
Get the JS file.
Smooth
With smooth scrolling and parallax.
<div data-scroll-container>
<div data-scroll-section>
<h1 data-scroll>Hey</h1>
<p data-scroll>ð</p>
</div>
<div data-scroll-section>
<h2 data-scroll data-scroll-speed="1">What's up?</h2>
<p data-scroll data-scroll-speed="2">ð¬</p>
</div>
</div>
import LocomotiveScroll from 'locomotive-scroll';
const scroll = new LocomotiveScroll({
el: document.querySelector('[data-scroll-container]'),
smooth: true
});
Note: scroll-sections are optional but recommended to improve performance, particularly in long pages.
Advanced
Make it do what you want.
With methods
<section id="js-target">Come here please.</section>
import LocomotiveScroll from 'locomotive-scroll';
const scroll = new LocomotiveScroll();
const target = document.querySelector('#js-target');
scroll.scrollTo(target);
With events
<!-- Using modularJS -->
<div data-scroll data-scroll-call="function, module">Trigger</div>
<!-- Using jQuery events -->
<div data-scroll data-scroll-call="EVENT_NAME">Trigger</div>
<!-- Or do it your own way ð -->
<div data-scroll data-scroll-call="{y,o,l,o}">Trigger</div>
import LocomotiveScroll from 'locomotive-scroll';
const scroll = new LocomotiveScroll();
scroll.on('call', func => {
// Using modularJS
this.call(...func);
// Using jQuery events
$(document).trigger(func);
// Or do it your own way ð
});
Instance options
Option | Type | Default | Description |
---|---|---|---|
el | object | document | Scroll container element. |
name | string | 'scroll' | Data attribute prefix (data-scroll-xxxx ). |
offset | array(2) | [0,0] | Global in-view trigger offset : [bottom,top] Use a string with % to use a percentage of the viewport height.Use a numeric value for absolute pixels unit. E.g. ["30%",0] , [100,0] , ["30%", 100] |
repeat | boolean | false | Repeat in-view detection. |
smooth | boolean | false | Smooth scrolling. |
initPosition | object | { x: 0, y: 0 } | An object defining the initial scroll coordinates on a smooth instance. For example: { x: 0, y: 1000 } |
direction | string | vertical | Scroll direction: vertical or horizontal |
lerp | number | 0.1 | Linear interpolation (lerp) intensity. Float between 0 and 1 .This defines the "smoothness" intensity. The closer to 0 , the smoother. |
getDirection | boolean | false | Add direction to scroll event. |
getSpeed | boolean | false | Add speed to scroll event. |
class | string | is-inview | Element in-view class. |
initClass | string | has-scroll-init | Initialize class. |
scrollingClass | string | has-scroll-scrolling | Is scrolling class. |
draggingClass | string | has-scroll-dragging | Is dragging class. |
smoothClass | string | has-scroll-smooth | Has smooth scrolling class. |
scrollbarContainer | object | false | Specifies the container element for the scrollbar to be appended in. If false, scrollbar will be appended to the body. |
scrollbarClass | string | c-scrollbar | Scrollbar element class. |
multiplier | number | 1 | Factor applied to the scroll delta, allowing to boost/reduce scrolling speed (regardless of the platform). |
firefoxMultiplier | number | 50 | Boost scrolling speed of Firefox on Windows. |
touchMultiplier | number | 2 | Multiply touch action to scroll faster than finger movement. |
scrollFromAnywhere | boolean | false | By default locomotive-scroll listens for scroll events only on the scroll container ( el option). With this option set to true, it listens on the whole document instead. |
gestureDirection | string | vertical | Defines which gesture direction(s) scrolls in your instance. You can use :
|
tablet & smartphone | object | Object allowing to override some options for a particular context. You can specify:
tablet context you can also define breakpoint (integer, defaults to 1024) to set the max-width breakpoint for tablets. | |
reloadOnContextChange | boolean | false | Allows to reload the page when switching between desktop , tablet and smartphone contexts. It can be useful if your page changes a lot between contexts and you want to reset everything. |
resetNativeScroll | boolean | true | Sets history.scrollRestoration = 'manual' and calls window.scrollTo(0, 0) on locomotive-scroll init in Native Class. Useful if you use transitions with native scrolling, otherwise we advise to set it to false if you don't want to break History API's scroll restoration feature. |
Element attributes
Attribute | Values | Description |
---|---|---|
data-scroll | Detect if in-view. | |
data-scroll-id | string | (Optional) Useful if you want to scope your element and get the progress of your element in the viewport for example. |
data-scroll-container | Defines the scroll container. Required for basic styling. | |
data-scroll-section | Defines a scrollable section. Splitting your page into sections may improve performance. | |
data-scroll-class | string | Element in-view class. |
data-scroll-offset | string | Element in-view trigger offset : bottom,top First value is bottom offset, second (optional) is top offset.Percent is relative to viewport height, otherwise it's absolute pixels. E.g. "10" , "100,50%" , "25%, 15%" |
data-scroll-repeat | boolean | Element in-view detection repeat. |
data-scroll-call | string | Element in-view trigger call event. |
data-scroll-position | string | top , bottom , left or right Window position of in-view trigger. |
data-scroll-speed | number | Element parallax speed. A negative value will reverse the direction. |
data-scroll-delay | number | Element's parallax lerp delay. |
data-scroll-direction | string | Element's parallax direction. vertical or horizontal |
data-scroll-sticky | Sticky element. Starts and stops at data-scroll-target position. | |
data-scroll-target | string | Target element's in-view position. |
Instance methods
Method | Description | Arguments |
---|---|---|
init() | Reinitializes the scroll. | |
on(eventName, function) | Listen instance events â¬. | |
update() | Updates all element positions. | |
destroy() | Destroys the scroll events. | |
start() | Restarts the scroll events. | |
stop() | Stops the scroll events. | |
scrollTo(target, options) | Scroll to a target. | target : Defines where you want to scroll. Available values types are :
options (optional, object) : Settings object. Available values are:
|
Instance events
Event | Arguments | Description |
---|---|---|
scroll | obj | Returns scroll instance (position, limit, speed, direction and current in-view elements). |
call | func | Trigger if in-view. Returns your string or array if contains , . |
Progressive playing animations example (like gsap)
All data-scroll
elements have a progress value.
In the on scroll event you can get all current in-view elements.
HTML
<h1 data-scroll data-scroll-id="hey">Hey</h1>
JS
scroll.on('scroll', (args) => {
// Get all current elements : args.currentElements
if(typeof args.currentElements['hey'] === 'object') {
let progress = args.currentElements['hey'].progress;
console.log(progress);
// ouput log example: 0.34
// gsap example : myGsapAnimation.progress(progress);
}
});
Dependencies
Name | Description |
---|---|
Virtual Scroll | Custom scroll event with inertia/momentum. |
modularScroll | Elements in viewport detection. Forked from it, not a dependency. |
bezier-easing | Allows to define an easing to scrollTo movement |
Browser support
Works on most modern browsers. Chrome, Firefox, Safari, Edge...
To get IE 11 support, you need polyfills. You can use your own or include these before our script.
<script nomodule src="https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/7.6.0/polyfill.min.js" crossorigin="anonymous"></script>
<script nomodule src="https://cdnjs.cloudflare.com/polyfill/v3/polyfill.min.js?features=Object.assign%2CElement.prototype.append%2CNodeList.prototype.forEach%2CCustomEvent%2Csmoothscroll" crossorigin="anonymous"></script>
Who's using Locomotive Scroll?
- thierrychopain.com
- clmt.paris
- miragefestival.com/2020
- mazellier.design
- ccccontemple.com
- abhishekjha.me/muteza
- normal.studio
- mixlegno.com
- nfq.group
- works.studio
- beangels.eu
- izakaya-caen.fr
- white-elephant.fr
- henge07.com
- loirevalleylodges.com
Related
Top Related Projects
Simple & lightweight (<4kb gzipped) vanilla JavaScript library to create smooth & beautiful animations when you scroll.
The javascript library for magical scroll interactions.
Animate on scroll library
🚀 Performance focused, lightweight scroll animation library 🚀
Most modern mobile touch slider with hardware accelerated transitions
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot