Locomotive Scroll — это библиотека для создания плавного скроллинга и
анимаций на основе скролла. Она управляет положением контента с помощью
виртуального скролла, изменяя transform: translate3d
контейнера вместо стандартного браузерного скролла. Это позволяет
создавать эффект параллакса, задержки движения элементов и другие
динамические визуальные эффекты.
При этом возникают конфликты с нативным поведением браузера, другими
библиотеками анимаций и CSS-свойствами, особенно с
position: fixed и overflow. Понимание того,
как Locomotive Scroll обрабатывает позиционирование, является ключом к
решению большинства проблем.
Фиксированная позиция элементов
(position: fixed) Locomotive Scroll не использует
стандартный скролл страницы, а создает виртуальный контейнер, который
смещается через transform. В результате элементы с
position: fixed перестают вести себя как фиксированные
относительно окна и начинают смещаться вместе с контейнером.
Конфликты с другими библиотеками анимаций
Библиотеки, работающие с нативным скроллом
(GSAP ScrollTrigger, AOS и др.), могут
получать некорректные значения прокрутки, если их скрипты не
синхронизированы с Locomotive Scroll.
Перекрытие событий колесика мыши или тача Если одновременно используется кастомная обработка событий скролла или touch-событий, возможны двойные срабатывания, «рывки» или блокировки скролла.
Проблемы с CSS-свойствами контейнера Locomotive
Scroll требует, чтобы контейнер имел overflow: hidden на
родителе и data-scroll-container на основном контейнере.
Любые вмешательства, например анимация height или
overflow на родителе, могут нарушать работу
скролла.
Чтобы элементы оставались фиксированными:
data-scroll-sticky вместо
position: fixed.<div data-scroll data-scroll-sticky data-scroll-target="#section1">
Я остаюсь «приклеенным» внутри секции
</div>
data-scroll-target указывает границы действия эффекта
sticky.data-scroll-container и использовать обычный
position: fixed.const scroll = new LocomotiveScroll({
el: document.querySelector("[data-scroll-container]"),
smooth: true
});
scroll.on("scroll", ScrollTrigger.update);
ScrollTrigger.scrollerProxy("[data-scroll-container]", {
scrollTop(value) {
return arguments.length ? scroll.scrollTo(value, 0, 0) : scroll.scroll.instance.scroll.y;
},
getBoundingClientRect() {
return { top: 0, left: 0, width: window.innerWidth, height: window.innerHeight };
},
pinType: document.querySelector("[data-scroll-container]").style.transform ? "transform" : "fixed"
});
const scroll = new LocomotiveScroll({
el: document.querySelector("[data-scroll-container]"),
smooth: true,
smartphone: {
smooth: true
},
tablet: {
smooth: true
}
});
<body> и иметь
data-scroll-container.height, overflow или
transform.Пример корректной структуры:
<body>
<div data-scroll-container>
<section data-scroll-section>
<h1 data-scroll data-scroll-speed="2">Параллакс заголовка</h1>
</section>
<section data-scroll-section>
<p data-scroll data-scroll-speed="1">Контент</p>
</section>
</div>
</body>
update():scroll.update();
imagesLoaded:imagesLoaded(document.querySelector('[data-scroll-container]'), () => {
scroll.update();
});
window.addEventListener("resize", () => {
scroll.update();
});
scroll.on('scroll', callback) для
отслеживания фактических координат скролла.position: fixed с контейнером
Locomotive Scroll без корректного обхода через
data-scroll-sticky.update().Эти практики обеспечивают стабильную работу виртуального скролла и позволяют избежать распространённых конфликтов при использовании Locomotive Scroll.