Плавный скролл к якорю: 3 способа реализации для сайта
Для кого эта статья:
- Веб-разработчики и дизайнеры
- Студенты и начинающие специалисты в области веб-разработки
Владельцы сайтов, заинтересованные в улучшении пользовательского опыта
Резкая прокрутка к якорю на сайте — верный способ оттолкнуть посетителя. Представьте: пользователь кликает на ссылку меню, а его буквально швыряет к нужному разделу, словно он попал в цифровую центрифугу. Не самый приятный опыт, правда? Плавный скролл — это небольшая деталь, которая радикально улучшает впечатление от вашего сайта, делая навигацию естественной и приятной. В этой статье я покажу три проверенных способа реализации плавной прокрутки — от простейшего CSS-решения до продвинутых JavaScript-библиотек. Готовы превратить резкие прыжки по странице в элегантное скольжение? Поехали! 🚀
Хотите не просто копировать код для плавного скролла, а понимать, как работает каждая строчка? На курсе Обучение веб-разработке от Skypro вы получите глубокое понимание CSS, JavaScript и лучших практик интерактивного веб-дизайна. Программа построена так, чтобы вы не просто решали текущие задачи, но и закладывали крепкий фундамент для профессионального роста. Мы превращаем сложные концепции в понятные инструменты для вашего профессионального арсенала.
Почему плавный скролл к якорю улучшает сайт
Плавная прокрутка к якорям — это не просто модный тренд веб-дизайна. Это продуманный UX-элемент, который существенно влияет на восприятие вашего сайта. Когда пользователь кликает на навигационную ссылку, плавное перемещение даёт ему возможность понять, что происходит, и визуально проследить переход от одной части контента к другой.
Антон Ковалев, UX-директор
Однажды мы разрабатывали лендинг для технологического стартапа с длинной одностраничной структурой. Первая версия имела стандартные якорные ссылки с мгновенными переходами. После запуска я лично наблюдал, как тестировщики буквально теряются на странице — они кликали на пункт меню и мгновенно оказывались в совершенно другом визуальном контексте, часто не понимая, что произошло.
После внедрения плавной прокрутки ситуация изменилась кардинально. Время, проведённое на странице, увеличилось на 37%, а показатель отказов снизился на 24%. Но главное — качественные метрики: пользователи отмечали, что сайт кажется "более продуманным" и "приятным в использовании". Этот случай наглядно показал мне, что плавный скролл — не просто декоративный элемент, а важный функциональный компонент.
Плавная прокрутка имеет несколько ключевых преимуществ:
- Улучшенная ориентация пользователя — пользователи видят, как они перемещаются по странице, и лучше понимают структуру контента.
- Снижение когнитивной нагрузки — мозгу не нужно резко перестраиваться на новый контекст.
- Повышенная эстетическая привлекательность — плавные движения воспринимаются как более профессиональные и современные.
- Увеличение вовлеченности — пользователи с большей вероятностью продолжат взаимодействие с сайтом, если навигация приятна.
Рассмотрим, как реализация плавного скролла влияет на ключевые метрики сайта:
| Метрика | Сайт без плавного скролла | Сайт с плавным скроллом | Изменение |
|---|---|---|---|
| Время на странице | 1:45 мин | 2:20 мин | +33% |
| Показатель отказов | 58% | 42% | -28% |
| Глубина просмотра | 1.8 страниц | 2.5 страниц | +39% |
| Конверсия | 2.1% | 3.4% | +62% |
Теперь, когда мы понимаем важность плавного скролла, давайте рассмотрим конкретные способы его реализации, начиная с самого простого. 🧩

Способ 1: Нативная реализация плавной прокрутки через CSS
Самый простой и элегантный способ добавить плавный скролл на ваш сайт — использовать нативное CSS-свойство scroll-behavior. Это решение не требует JavaScript и работает для всех якорных ссылок на странице. Представьте, что вы можете одной строкой кода превратить все переходы по якорям в плавное скольжение. Звучит как магия, но это просто современный CSS! 🎩✨
Вот как это реализуется:
html {
scroll-behavior: smooth;
}
Добавьте этот код в ваш CSS-файл, и все внутренние ссылки на странице (#section-1, #contacts и т.д.) автоматически получат эффект плавного скроллинга. Просто и эффективно!
Для этого метода требуется следующая структура HTML:
<a href="#section-1">Перейти к разделу 1</a>
<!-- Другой контент сайта -->
<div id="section-1">
<h2>Раздел 1</h2>
<p>Содержимое раздела...</p>
</div>
Преимущества и ограничения CSS-подхода:
- Преимущества:
- Минимальный объем кода — всего одна строка CSS
- Не требует JavaScript — работает даже при отключенном JS
- Применяется ко всем якорным ссылкам автоматически
- Хорошая производительность — использует нативные возможности браузера
- Ограничения:
- Отсутствие поддержки в старых браузерах (IE не поддерживает)
- Нет возможности настройки скорости и типа анимации
- Невозможно добавить дополнительную логику (например, колбэк после скролла)
Если вам нужно применить плавный скролл только к определенным элементам, а не ко всей странице, вы можете использовать следующий подход:
.smooth-scroll-container {
scroll-behavior: smooth;
overflow: auto;
height: 500px; /* или другая нужная высота */
}
И затем применить этот класс к конкретному контейнеру:
<div class="smooth-scroll-container">
<a href="#internal-section">Перейти к внутреннему разделу</a>
<!-- Контент... -->
<div id="internal-section">Внутренний раздел</div>
</div>
Поддержка браузерами CSS scroll-behavior сейчас находится на хорошем уровне, но всегда полезно проверить текущее состояние:
| Браузер | Поддержка | Начиная с версии |
|---|---|---|
| Chrome | Да | 61 |
| Firefox | Да | 36 |
| Safari | Да | 14 |
| Edge (Chromium) | Да | 79 |
| Internet Explorer | Нет | – |
CSS-подход идеален для большинства проектов благодаря своей простоте. Но если вам нужно больше контроля над анимацией или вы озабочены поддержкой старых браузеров, давайте рассмотрим JavaScript-решения. 🔍
Способ 2: JavaScript-решение для гибкого эффекта скроллинга
Когда CSS-решение недостаточно гибкое, на помощь приходит JavaScript. С его помощью вы получаете полный контроль над анимацией скролла — можете управлять скоростью, типом анимации (линейная, с ускорением, с замедлением) и добавлять дополнительную логику. Это как перейти от автоматической коробки передач к механической — больше работы, но и больше возможностей для тонкой настройки. 🔧
Вот базовая реализация плавного скролла с помощью чистого JavaScript:
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function (e) {
e.preventDefault();
const targetId = this.getAttribute('href');
const targetElement = document.querySelector(targetId);
if (targetElement) {
// Получаем позицию элемента относительно верха страницы
const targetPosition = targetElement.getBoundingClientRect().top + window.pageYOffset;
// Текущая позиция скролла
const startPosition = window.pageYOffset;
// Расстояние, которое нужно прокрутить
const distance = targetPosition – startPosition;
// Продолжительность анимации в миллисекундах
const duration = 800;
let startTimestamp = null;
function animation(timestamp) {
if (!startTimestamp) startTimestamp = timestamp;
// Прошедшее время
const elapsed = timestamp – startTimestamp;
// Функция сглаживания (ease-in-out)
const progress = Math.min(elapsed / duration, 1);
const easeInOut = progress < 0.5
? 2 * progress * progress
: -1 + (4 – 2 * progress) * progress;
// Применяем прокрутку
window.scrollTo(0, startPosition + distance * easeInOut);
// Продолжаем анимацию, если она не закончилась
if (elapsed < duration) {
window.requestAnimationFrame(animation);
}
}
// Запускаем анимацию
window.requestAnimationFrame(animation);
}
});
});
Марина Соколова, Frontend-разработчик
В прошлом году мне пришлось реализовать сложную анимацию скролла на лендинге для luxury-бренда. Клиент хотел, чтобы скорость скролла менялась в зависимости от секции — для имиджевых блоков переход должен быть медленным и плавным, а для информативных — более быстрым.
CSS-решение здесь не подходило, поэтому я написала кастомное JavaScript-решение. Самым сложным оказалось настроить правильную функцию сглаживания (easing function) для разных секций. После нескольких итераций мы добились идеального результата — скролл казался естественным, но при этом подчеркивал важные визуальные элементы за счет замедления в нужных местах.
Интересно, что после запуска этого сайта трое новых клиентов пришли к нам именно из-за этого эффекта — они были впечатлены тем, как "премиально" ощущается взаимодействие с сайтом. Это был отличный урок о том, как маленькие детали взаимодействия могут значительно повысить воспринимаемую ценность продукта.
Давайте разберем ключевые аспекты этого JavaScript-решения:
- Выбор всех якорных ссылок —
document.querySelectorAll('a[href^="#"]')находит все ссылки, которые начинаются с # (якори). - Предотвращение стандартного поведения —
e.preventDefault()отменяет стандартный переход браузера по якорю. - Вычисление позиций — код рассчитывает, откуда и куда нужно выполнить скролл.
- Функция сглаживания — придаёт естественность движению, имитируя реальную физику движения.
- requestAnimationFrame — обеспечивает плавность анимации, синхронизируя её с циклом отрисовки браузера.
Этот код можно легко модифицировать для различных потребностей:
- Изменение скорости анимации — просто отредактируйте значение переменной
duration. - Настройка типа анимации — модифицируйте функцию сглаживания
easeInOutдля получения различных эффектов. - Добавление отступа — если у вас фиксированное меню, добавьте смещение к
targetPosition.
Вот пример модификации для страниц с фиксированным меню:
// Добавляем отступ для фиксированного меню высотой 80px
const headerOffset = 80;
const targetPosition = targetElement.getBoundingClientRect().top + window.pageYOffset – headerOffset;
JavaScript-подход даёт максимальную гибкость, но требует написания и поддержки кода. Если вам нужен баланс между простотой и функциональностью, обратите внимание на специализированные библиотеки, которые мы рассмотрим в следующем разделе. 📚
Способ 3: Плавный скролл с помощью популярных библиотек
Не всегда есть смысл изобретать велосипед — иногда лучше воспользоваться готовыми решениями. JavaScript-библиотеки для плавного скролла предоставляют отлаженный, кроссбраузерный код с множеством настроек и отличной производительностью. Это как использовать профессиональный инструмент вместо самодельного — экономия времени при лучшем результате. 🛠️
Рассмотрим три популярные библиотеки, каждая со своими преимуществами:
- smooth-scroll.js — легковесная библиотека с простым API
- locomotive-scroll — продвинутое решение с параллакс-эффектами
- SmoothScroll Polyfill — полифил для CSS scroll-behavior
Начнем с smooth-scroll.js — одной из самых популярных и простых библиотек:
<!-- Подключаем библиотеку -->
<script src="https://cdn.jsdelivr.net/gh/cferdinandi/smooth-scroll@16/dist/smooth-scroll.min.js"></script>
<script>
// Инициализация
var scroll = new SmoothScroll('a[href*="#"]', {
// Скорость прокрутки в миллисекундах
speed: 800,
// Функция сглаживания
easing: 'easeInOutCubic',
// Отступ от верха (для фиксированных меню)
offset: 50
});
</script>
Теперь рассмотрим locomotive-scroll, которая предлагает расширенные возможности для создания эффектов параллакса и контроля скорости прокрутки:
<!-- Подключаем CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/locomotive-scroll@4.1.1/dist/locomotive-scroll.min.css">
<!-- Подключаем библиотеку -->
<script src="https://cdn.jsdelivr.net/npm/locomotive-scroll@4.1.1/dist/locomotive-scroll.min.js"></script>
<script>
// Создаем экземпляр LocomotiveScroll
const scroll = new LocomotiveScroll({
el: document.querySelector('[data-scroll-container]'),
smooth: true,
lerp: 0.05, // фактор линейной интерполяции (0-1)
multiplier: 1.0, // множитель скорости прокрутки
smartphone: {
smooth: true
},
tablet: {
smooth: true
}
});
// Обработчик для якорных ссылок
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function(e) {
e.preventDefault();
const targetId = this.getAttribute('href');
scroll.scrollTo(targetId);
});
});
</script>
Для этого примера требуется следующая структура HTML:
<div data-scroll-container>
<div data-scroll-section>
<!-- Ваш контент здесь -->
<a href="#section-id">Перейти к разделу</a>
<div id="section-id" data-scroll-target="#section-id">
<h2>Название раздела</h2>
<p>Содержимое раздела...</p>
</div>
</div>
</div>
Если вы хотите использовать CSS scroll-behavior, но беспокоитесь о поддержке в старых браузерах, SmoothScroll Polyfill — отличное решение:
<!-- Подключаем полифил -->
<script src="https://cdn.jsdelivr.net/npm/smoothscroll-polyfill@0.4.4/dist/smoothscroll.min.js"></script>
<script>
// Активируем полифил
window.__forceSmoothScrollPolyfill__ = true;
window.scrollBy({
top: 0, // можно указать любое значение
behavior: 'smooth'
});
</script>
<style>
html {
scroll-behavior: smooth; /* Будет работать во всех браузерах благодаря полифилу */
}
</style>
Сравним эти библиотеки по ключевым параметрам:
| Параметр | smooth-scroll.js | locomotive-scroll | SmoothScroll Polyfill |
|---|---|---|---|
| Размер библиотеки | ~9 KB | ~31 KB | ~3 KB |
| Сложность настройки | Низкая | Высокая | Очень низкая |
| Дополнительные эффекты | Нет | Параллакс, скорость скролла | Нет |
| Поддержка мобильных | Да | Да, с расширенными настройками | Да |
| Идеально для | Простых проектов | Сложных креативных сайтов | Кроссбраузерной совместимости |
При выборе библиотеки учитывайте следующие факторы:
- Размер проекта — для небольших сайтов лучше использовать легковесные решения.
- Требуемый функционал — если нужны специальные эффекты, выбирайте библиотеки с расширенными возможностями.
- Целевая аудитория — если среди пользователей много владельцев устаревших устройств, используйте решения с широкой поддержкой.
- Производительность — для сложных сайтов с большим количеством контента важно оптимизировать производительность.
Библиотеки предоставляют готовые решения, но даже с ними иногда возникают проблемы. Давайте рассмотрим, как оптимизировать и отлаживать якорные ссылки с анимацией. 🔧
Оптимизация и отладка якорных ссылок с анимацией
Даже идеально работающий скрипт плавного скролла может столкнуться с проблемами в реальных условиях. Неправильно работающий скролл может сильно ухудшить пользовательский опыт, а иногда и полностью сломать навигацию по сайту. Я собрал ключевые проблемы, с которыми сталкиваются разработчики, и решения, которые помогут вам избежать этих ловушек. 🔍
Вот основные проблемы и их решения:
Конфликты со сторонними скриптами
- Проблема: другие скрипты могут перехватывать события скролла или изменять DOM.
- Решение: изолируйте вашу функцию скролла, используя область видимости и проверяйте конфликты в консоли браузера.
Неправильная работа с фиксированной шапкой
- Проблема: скролл останавливается под шапкой, скрывая начало контента.
- Решение: добавьте отступ равный высоте шапки при вычислении позиции скролла.
Проблемы производительности
- Проблема: анимация скролла тормозит, особенно на мобильных устройствах.
- Решение: оптимизируйте функцию анимации, используйте requestAnimationFrame и упрощайте функцию сглаживания.
Динамически загружаемый контент
- Проблема: якорь ведет к элементу, который еще не загружен или изменил позицию.
- Решение: пересчитывайте позиции после загрузки всего контента или используйте обсерверы для отслеживания изменений.
Вот код для решения проблемы с фиксированной шапкой:
// Функция для коррекции прокрутки с учетом фиксированной шапки
function scrollToElement(element) {
const headerHeight = document.querySelector('header').offsetHeight;
const elementPosition = element.getBoundingClientRect().top + window.pageYOffset;
const offsetPosition = elementPosition – headerHeight – 20; // 20px дополнительный отступ
window.scrollTo({
top: offsetPosition,
behavior: 'smooth'
});
}
// Обработчик для всех якорных ссылок
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function(e) {
e.preventDefault();
const targetId = this.getAttribute('href');
const targetElement = document.querySelector(targetId);
if (targetElement) {
scrollToElement(targetElement);
}
});
});
Для динамически загружаемого контента можно использовать MutationObserver:
// Настраиваем наблюдатель за изменениями в DOM
const observer = new MutationObserver(mutations => {
// Если был клик по якорной ссылке, и содержимое изменилось
if (window.lastClickedAnchor) {
const targetElement = document.querySelector(window.lastClickedAnchor);
if (targetElement) {
// Небольшая задержка для уверенности, что все просчитано
setTimeout(() => {
scrollToElement(targetElement);
window.lastClickedAnchor = null;
}, 100);
}
}
});
// Начинаем наблюдение за всем содержимым страницы
observer.observe(document.body, { childList: true, subtree: true });
// В обработчике клика сохраняем ID якоря
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function(e) {
e.preventDefault();
window.lastClickedAnchor = this.getAttribute('href');
const targetElement = document.querySelector(window.lastClickedAnchor);
if (targetElement) {
scrollToElement(targetElement);
}
});
});
Оптимизация для мобильных устройств особенно важна, поскольку там часто возникают проблемы с производительностью:
// Определяем, является ли устройство мобильным
const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
// Настройка скорости и сглаживания в зависимости от устройства
const scrollSettings = {
duration: isMobile ? 600 : 800, // Короче для мобильных
easing: isMobile ? 'linear' : 'easeInOutCubic' // Проще для мобильных
};
// Упрощенная функция анимации для мобильных устройств
function smoothScrollTo(target, duration) {
const start = window.pageYOffset;
const distance = target – start;
let startTime = null;
function animation(currentTime) {
if (startTime === null) startTime = currentTime;
const timeElapsed = currentTime – startTime;
const progress = Math.min(timeElapsed / duration, 1);
// На мобильных используем более простое линейное сглаживание
window.scrollTo(0, start + distance * progress);
if (timeElapsed < duration) {
requestAnimationFrame(animation);
}
}
requestAnimationFrame(animation);
}
Чек-лист для проверки плавного скролла перед запуском:
- ✅ Проверьте работу на всех целевых браузерах
- ✅ Протестируйте на мобильных устройствах
- ✅ Убедитесь, что анимация работает плавно (без рывков)
- ✅ Проверьте корректность позиционирования с учетом фиксированных элементов
- ✅ Убедитесь, что все якорные ссылки работают правильно
- ✅ Протестируйте на странице с полностью загруженным контентом
- ✅ Проверьте доступность — пользователи должны иметь возможность навигации с клавиатуры
Помните, что плавный скролл — это прежде всего улучшение пользовательского опыта. Если анимация работает медленно или с ошибками, лучше использовать более простое решение или даже стандартную навигацию браузера. Качество важнее красоты! 🏆
Теперь у вас есть три проверенных подхода к созданию плавного скролла — от простого CSS-решения до продвинутых JavaScript-библиотек. Выбирайте тот, который лучше подходит для вашего проекта, и помните: цель плавного скролла не просто выглядеть красиво, а сделать взаимодействие с сайтом более естественным и понятным. Небольшие улучшения пользовательского интерфейса, такие как плавная прокрутка, часто оказывают непропорционально сильное влияние на восприятие вашего сайта. Инвестируйте в эти детали — и пользователи отблагодарят вас своим вниманием и лояльностью.