Плавный скролл в CSS


Переход по якорным ссылкам внутри страницы мгновенно «перебрасывает» к нужному месту:

<a class="back-to-top" href="#top">Scroll to Top</a>

Такое моментальное перемещение может вызвать непонимание, что именно произошло, а это плохой UX. Именно поэтому такой скролл лучше делать плавным, чтобы было видно явно, откуда скролл «выехал» и где остановился.

Нативное решение можно сделать и на JS, и на CSS.

JS-решение

В метод scroll или scrollIntoView передаётся настройка behavior: 'smooth':

const backLink = document.querySelector(".back-to-top");
backLink.addEventListener("click", (e) => {
// отключаем «перескок» по умолчанию
e.preventDefault();
// плавно скроллим к самому верху страницы
window.scroll({ top: 0, behavior: "smooth" });
// или скроллим к элементу с id="top"
document.querySelector("#top").scrollIntoView({ behavior: "smooth" });
});

CSS-решение

Контейнеру со скроллом задаётся свойство scroll-behavior. Это может быть и вся страница, то есть контейнер самого верхнего уровня — html:

html {
scroll-behavior: smooth;
}

Когда скролл к элементу произошёл, то верхняя часть экрана «упрётся» прямо в блок, к которому произошёл скролл. Чтобы такого «прилипания» не произошло, можно воспользоваться свойством scroll-margin, которое задаст элементу внешние отступы, учитывающиеся только при скролле.

#top {
scroll-margin-top: 20px;
}

Таким образом от верхнего края экрана до блока, к которому произошёл скролл, останется «зазор» в 20 пикселей.