Стилизация через scrollbarContainer

В библиотеке Locomotive Scroll параметр scrollbarContainer отвечает за размещение кастомного скроллбара в пределах указанного DOM-элемента. По умолчанию скроллбар добавляется в body, однако при необходимости его можно изолировать и стилизовать в рамках конкретного контейнера.

Это особенно важно при создании сложных интерфейсов, где:

  • используется фиксированная верстка
  • требуется ограничить область прокрутки
  • необходимо интегрировать скроллбар в дизайн конкретного блока

Подключение scrollbarContainer

При инициализации Locomotive Scroll параметр указывается в конфигурации:

const scroll = new LocomotiveScroll({
  el: document.querySelector('[data-scroll-container]'),
  smooth: true,
  scrollbarContainer: document.querySelector('.scrollbar-wrapper')
});

В данном случае:

  • основной скролл происходит внутри [data-scroll-container]
  • визуальный скроллбар будет размещен внутри .scrollbar-wrapper

Структура DOM

Для корректной работы важно заранее подготовить HTML-структуру:

<div class="scrollbar-wrapper"></div>

<div data-scroll-container>
  <section data-scroll-section>
    Контент
  </section>
</div>

Ключевые моменты:

  • контейнер для скроллбара должен существовать до инициализации
  • он не должен находиться внутри data-scroll-container
  • рекомендуется размещать его на одном уровне с основным контейнером

Внутреннее устройство скроллбара

Locomotive Scroll автоматически создаёт следующие элементы:

<div class="c-scrollbar">
  <div class="c-scrollbar_thumb"></div>
</div>

Если задан scrollbarContainer, эта структура будет вставлена внутрь него.


Базовая стилизация

Минимальный набор стилей:

.scrollbar-wrapper {
  position: fixed;
  top: 0;
  right: 10px;
  width: 8px;
  height: 100vh;
}

.c-scrollbar {
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.1);
}

.c-scrollbar_thumb {
  width: 100%;
  background: #000;
  border-radius: 4px;
  cursor: grab;
}

Особенности:

  • высота должна соответствовать области прокрутки
  • ширина влияет на визуальную “толщину” скроллбара
  • cursor: grab улучшает UX

Управление позиционированием

Поскольку контейнер задаётся вручную, появляется полный контроль над размещением:

Фиксированное положение

.scrollbar-wrapper {
  position: fixed;
  right: 20px;
  top: 50px;
  height: calc(100vh - 100px);
}

Встраивание в layout

.scrollbar-wrapper {
  position: absolute;
  right: 0;
  top: 0;
  height: 100%;
}

Кастомизация внешнего вида

Прозрачный фон

.c-scrollbar {
  background: transparent;
}

Градиент

.c-scrollbar_thumb {
  background: linear-gradient(to bottom, #ff7a18, #af002d);
}

Скругление и тени

.c-scrollbar_thumb {
  border-radius: 10px;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
}

Анимация скроллбара

Locomotive Scroll сам управляет позицией thumb, но можно добавить визуальные эффекты:

Плавное появление

.c-scrollbar {
  opacity: 0;
  transition: opacity 0.3s;
}

.has-scroll-scrolling .c-scrollbar {
  opacity: 1;
}

Эффект увеличения при наведении

.c-scrollbar_thumb {
  transition: transform 0.2s;
}

.c-scrollbar_thumb:hover {
  transform: scaleX(1.5);
}

Скрытие нативного скроллбара

При использовании кастомного скролла важно убрать стандартный:

html, body {
  overflow: hidden;
}

Адаптация под горизонтальный скролл

Если используется горизонтальная прокрутка:

const scroll = new LocomotiveScroll({
  el: document.querySelector('[data-scroll-container]'),
  direction: 'horizontal',
  scrollbarContainer: document.querySelector('.scrollbar-wrapper')
});

Стили:

.scrollbar-wrapper {
  bottom: 10px;
  left: 0;
  width: 100%;
  height: 8px;
}

.c-scrollbar_thumb {
  height: 100%;
  width: auto;
}

Синхронизация с кастомным UI

При необходимости можно синхронизировать скроллбар с другими элементами интерфейса:

scroll.on('scroll', (args) => {
  const progress = args.scroll.y / args.limit.y;
  document.querySelector('.progress-bar').style.width = `${progress * 100}%`;
});

Частые ошибки

1. Контейнер отсутствует в DOM

  • скроллбар не появится

2. Неверное позиционирование

  • скроллбар может “выпасть” из области видимости

3. Перекрытие z-index

.scrollbar-wrapper {
  z-index: 1000;
}

4. Конфликт с overflow

.scrollbar-wrapper {
  overflow: hidden;
}

Расширенные сценарии

Несколько скроллбаров

Можно создать независимые экземпляры:

new LocomotiveScroll({
  el: document.querySelector('.container-1'),
  scrollbarContainer: document.querySelector('.scrollbar-1')
});

new LocomotiveScroll({
  el: document.querySelector('.container-2'),
  scrollbarContainer: document.querySelector('.scrollbar-2')
});

Динамическое изменение контейнера

scroll.options.scrollbarContainer = document.querySelector('.new-container');
scroll.update();

Полное отключение скроллбара

const scroll = new LocomotiveScroll({
  scrollbarContainer: false
});

Практические рекомендации

  • использовать отдельный контейнер для сложных интерфейсов
  • избегать вложенности внутри скроллируемого блока
  • контролировать размеры через vh и calc()
  • добавлять анимации только через CSS, не вмешиваясь в JS-логику библиотеки
  • учитывать мобильные устройства — кастомный скроллбар часто отключается

Производительность и оптимизация

  • минимизировать количество CSS-эффектов (особенно box-shadow)
  • не использовать тяжёлые фильтры (blur, backdrop-filter)
  • избегать частых DOM-манипуляций внутри scroll-событий
  • проверять работу при smooth: false

Взаимодействие с другими библиотеками

При использовании с анимационными библиотеками (например, GSAP):

scroll.on('scroll', ScrollTrigger.update);

Скроллбар при этом остаётся независимым, но визуально синхронизированным.


Итоговая архитектура

  • data-scroll-container — зона прокрутки
  • scrollbarContainer — зона отображения скроллбара
  • .c-scrollbar — трек
  • .c-scrollbar_thumb — индикатор позиции

Такое разделение даёт полный контроль над стилем, положением и поведением скроллбара без вмешательства в ядро библиотеки.