Что такое Smooth Scroll

Smooth Scroll — это техника плавного скроллинга страницы, которая заменяет резкое перемещение браузера к якорным ссылкам или определённым элементам DOM на постепенное анимированное перемещение. Она улучшает пользовательский опыт, делая навигацию более комфортной, особенно на длинных страницах с большим количеством контента.

В основе работы Smooth Scroll лежит изменение позиции окна просмотра с течением времени, а не мгновенное перескакивание. Это достигается через программное управление свойством scrollTop или методами window.scrollTo с использованием анимации через requestAnimationFrame.


Методы реализации в JavaScript

Существует несколько подходов к реализации плавного скролла:

1. Встроенный метод scrollIntoView

const element = document.querySelector('#target');
element.scrollIntoView({ beh * avior: 'smooth', block: 'start' });

Пояснения:

  • beh * avior: 'smooth' — активирует плавный скролл.
  • block: 'start' — позиционирует элемент в начале окна просмотра.
  • Поддерживается современными браузерами (Chrome, Firefox, Edge, Safari).

Недостатком является ограниченная гибкость: невозможно управлять скоростью или кривой анимации.

2. Использование window.scrollTo с плавной прокруткой

window.scrollTo({
  top: 500,
  left: 0,
  beh * avior: 'smooth'
});
  • top — конечная вертикальная координата.
  • left — конечная горизонтальная координата.
  • beh * avior: 'smooth' задаёт плавность.

Эта конструкция полезна для скролла к конкретной позиции страницы, а не к элементу напрямую.

3. Реализация через requestAnimationFrame

Для более тонкой настройки анимации можно написать кастомный скролл:

function smoothScroll(target, duration = 600) {
  const start = window.scrollY;
  const end = target.getBoundingClientRect().top + start;
  const distance = end - start;
  let startTime = null;

  function animation(currentTime) {
    if (!startTime) startTime = currentTime;
    const timeElapsed = currentTime - startTime;
    const progress = Math.min(timeElapsed / duration, 1);
    const ease = progress < 0.5 
      ? 2 * progress * progress 
      : -1 + (4 - 2 * progress) * progress;

    window.scrollTo(0, start + distance * ease);
    if (timeElapsed < duration) requestAnimationFrame(animation);
  }

  requestAnimationFrame(animation);
}

const targetElement = document.querySelector('#target');
smoothScroll(targetElement, 800);

Пояснения к коду:

  • Используется кастомная функция ease, обеспечивающая естественное ускорение и замедление.
  • requestAnimationFrame гарантирует плавность на любых частотах обновления экрана.
  • Полная контроль над продолжительностью и кривой анимации.

Настройка кривых анимации (Easing)

Плавность скролла напрямую зависит от кривой анимации. Наиболее распространённые варианты:

  • Linear — постоянная скорость.
  • Ease-in — медленное начало, ускорение к концу.
  • Ease-out — быстрое начало, плавное замедление к концу.
  • Ease-in-out — сочетание ускорения и замедления.

Пример функции easeInOutQuad:

function easeInOutQuad(t) {
  return t < 0.5 ? 2*t*t : -1 + (4 - 2*t)*t;
}

Использование таких функций позволяет сделать скролл максимально естественным для глаз.


Работа с якорными ссылками

Часто Smooth Scroll применяется для навигации по странице через ссылки с href="#section":

document.querySelectorAll('a[href^="#"]').forEach(anchor => {
  anchor.addEventListener('click', function(e) {
    e.preventDefault();
    const target = document.querySelector(this.getAttribute('href'));
    smoothScroll(target, 700);
  });
});
  • Предотвращается стандартное мгновенное поведение браузера.
  • Все якорные ссылки могут быть подключены к единой функции плавного скролла.
  • Поддерживается адаптивная прокрутка, учитывающая динамический контент.

Советы по производительности

  • Избегать частого вычисления getBoundingClientRect внутри анимации; лучше кэшировать координаты.
  • Минимизировать сложные операции с DOM во время прокрутки.
  • Для длинных страниц и мобильных устройств использовать passive: true при добавлении обработчиков событий скролла, если это не мешает кастомной анимации.
  • Применять requestAnimationFrame вместо setInterval или setTimeout для синхронизации с частотой обновления экрана.

Особенности совместимости

  • Плавный скролл через beh * avior: 'smooth' поддерживается большинством современных браузеров.
  • Для старых версий (IE, старые Safari) необходим полифилл или кастомная реализация через requestAnimationFrame.
  • Для мобильных устройств важна оптимизация анимации: тяжелые easing-функции и частые перерасчёты могут привести к подтормаживанию.

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

  • Smooth Scroll легко интегрируется с SPA (React, Vue, Angular), но важно учитывать динамическую генерацию контента.
  • Возможна комбинация с scrollspy, чтобы отслеживать текущий раздел страницы.
  • Можно применять параллакс-эффекты и другие визуальные анимации вместе с плавным скроллом без конфликтов, если корректно управлять requestAnimationFrame.

Эта техника является основой современной веб-навигации и позволяет создавать страницы с плавным, отзывчивым и естественным скроллингом, значительно улучшая пользовательский опыт и визуальное восприятие контента.