Статьи

Как сделать кнопку «наверх» на сайте — просто и красиво

25 июля 2026  |  7 мин чтения

Кнопка «наверх» (back-to-top) — микроэлемент интерфейса, который заметно улучшает UX на длинных страницах, в блогах, каталогах и лендингах с большим объёмом контента. Когда пользователь пролистывает длинную страницу, ему не приходится скроллить обратно вручную или жать Home — кнопка делает это за одно нажатие. Несмотря на кажущуюся простоту, вокруг кнопки «наверх» сложилось множество приёмов, анимаций, вариаций дизайна и оптимизаций, которые мы разберём в этой статье.

Базовая реализация: HTML + CSS + JS

Начнём с минимального рабочего примера. Нам нужны: кнопка в HTML, стили для позиционирования и анимации появления, скрипт для отслеживания скролла и плавного подъёма.

HTML

<button id="backToTop" class="back-to-top" aria-label="Наверх страницы" title="Наверх">
  <i class="fas fa-arrow-up"></i>
</button>

Обратите внимание на aria-label — это важно для accessibility. Скринридеры зачитают «Наверх страницы» вместо бессмысленного «button». Атрибут title покажет подсказку при наведении.

CSS: базовая версия + анимация появления

.back-to-top {
  position: fixed;
  bottom: 30px;
  right: 30px;
  width: 48px;
  height: 48px;
  border: none;
  border-radius: 50%;
  background: var(--primary, #6c5ce7);
  color: #fff;
  font-size: 1.2rem;
  cursor: pointer;
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 0.3s ease, transform 0.3s ease;
  pointer-events: none;
  z-index: 999;
  box-shadow: 0 4px 15px rgba(108, 92, 231, 0.3);
  display: flex;
  align-items: center;
  justify-content: center;
}
.back-to-top.visible {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}
.back-to-top:hover {
  transform: translateY(-3px);
  box-shadow: 0 6px 20px rgba(108, 92, 231, 0.5);
}
.back-to-top:focus-visible {
  outline: 3px solid var(--primary);
  outline-offset: 4px;
}

Ключевые моменты: pointer-events: none при скрытом состоянии — пользователь не может случайно кликнуть по невидимой кнопке. opacity + transform дают плавное появление с подъёмом. :focus-visible обеспечивает клавиатурную навигацию.

JS: с throttle для производительности

const btn = document.getElementById('backToTop');

function throttle(fn, delay) {
  let last = 0;
  return function(...args) {
    const now = Date.now();
    if (now - last >= delay) {
      last = now;
      fn.apply(this, args);
    }
  };
}

window.addEventListener('scroll', throttle(() => {
  const threshold = window.innerHeight;
  btn.classList.toggle('visible', window.scrollY > threshold);
}, 100));

btn.addEventListener('click', () => {
  window.scrollTo({ top: 0, behavior: 'smooth' });
});

Без throttle событие scroll срабатывает десятки раз в секунду — это нагружает основной поток. С throttle в 100 мс проверка порога происходит максимум 10 раз в секунду. Порог window.innerHeight означает, что кнопка появляется, когда пользователь проскроллил хотя бы на высоту экрана.

Прогресс-бар вокруг кнопки (SVG circle)

Эффектный приём — отображать прогресс прочтения страницы по кругу вокруг кнопки. Реализуется через SVG circle с атрибутами stroke-dasharray и stroke-dashoffset:

<div class="back-to-top-wrapper">
  <svg class="progress-ring" width="56" height="56">
    <circle class="progress-ring__bg" cx="28" cy="28" r="24"
      fill="none" stroke="var(--border)" stroke-width="3"/>
    <circle class="progress-ring__fill" cx="28" cy="28" r="24"
      fill="none" stroke="var(--primary)" stroke-width="3"
      stroke-linecap="round"
      stroke-dasharray="150.8"
      stroke-dashoffset="150.8"/>
  </svg>
  <button class="back-to-top" id="backToTop" aria-label="Наверх">
    <i class="fas fa-arrow-up"></i>
  </button>
</div>

<style>
.back-to-top-wrapper {
  position: fixed;
  bottom: 30px;
  right: 30px;
  z-index: 999;
}
.back-to-top-wrapper .back-to-top {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 40px;
  height: 40px;
}
.progress-ring {
  transform: rotate(-90deg);
}
</style>

<script>
const circle = document.querySelector('.progress-ring__fill');
const circumference = 2 * Math.PI * 24;

window.addEventListener('scroll', () => {
  const scrollPct = window.scrollY / (document.documentElement.scrollHeight - window.innerHeight);
  const offset = circumference * (1 - Math.min(scrollPct, 1));
  circle.style.strokeDashoffset = offset;
});
</script>

Длина окружности 2 × π × 24 = 150.8. При скролле stroke-dashoffset уменьшается от 150.8 до 0, создавая эффект заполнения. Оборачивающий div позиционируется как fixed, а кнопка и SVG абсолютно центрируются внутри.

CSS-вариации: дизайн под любой стиль

1. Круглая с тенью (база)

Стандарт — круг 48×48px, цвет акцента, полупрозрачная тень. Минималистично и привычно.

2. Квадратная с градиентом

.back-to-top.square {
  border-radius: 12px;
  background: linear-gradient(135deg, #667eea, #764ba2);
  width: 44px;
  height: 44px;
}

Квадратная форма со скруглёнными углами (12px) и градиентом смотрится современно, особенно на сайтах с тёмной темой.

3. Glassmorphism

.back-to-top.glass {
  background: rgba(255, 255, 255, 0.15);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border: 1px solid rgba(255, 255, 255, 0.25);
  box-shadow: none;
  color: #fff;
}

Эффект стекла вписывается в современные нейморфные интерфейсы. Важно: backdrop-filter не работает в некоторых браузерах, проверяйте caniuse.

4. С подсветкой при наведении

.back-to-top.glowing {
  box-shadow: 0 0 15px rgba(var(--primary-rgb), 0.4);
  animation: pulse 2s infinite;
}
@keyframes pulse {
  0%, 100% { box-shadow: 0 0 15px rgba(var(--primary-rgb), 0.4); }
  50% { box-shadow: 0 0 25px rgba(var(--primary-rgb), 0.7); }
}

Intersection Observer вместо scroll

Современная альтернатива событию scroll — Intersection Observer. Он не нагружает основной поток и срабатывает только при пересечении указанного элемента с областью просмотра:

const sentinel = document.getElementById('scrollSentinel');
const btn = document.getElementById('backToTop');

const observer = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    btn.classList.toggle('visible', !entry.isIntersecting);
  });
}, { threshold: 0 });

observer.observe(sentinel);

Помещаем невидимый элемент высотой 1px в начало страницы. Пока он в области видимости — кнопка скрыта. Как только пользователь проскроллил дальше — появляется. Преимущество: Intersection Observer не вызывает reflow и работает в отдельном потоке браузера.

Когда показывать кнопку

ЛогикаКодКогда подходит
scrollY > высота экранаwindow.scrollY > window.innerHeightСтандартный вариант для всех страниц
scrollY > 30% страницыwindow.scrollY / docHeight > 0.3Для коротких страниц, где нужно показать раньше
После определённого блокаIntersection Observer на целевой секцииКогда кнопка нужна только после конкретного раздела

Доступность (Accessibility)

Кнопка «наверх» — интерактивный элемент, и она должна быть доступна всем пользователям:

aria-label="Наверх страницы" — скринридер прочитает осмысленное описание
role="button" — явно указывает роль (хотя для button это по умолчанию)
:focus-visible — видимый фокус при навигации с клавиатуры
tabindex="0" — кнопка фокусируется tab'ом (и так по умолчанию)
— При скрытом состоянии aria-hidden="true" — скринридер не видит невидимую кнопку

Мобильные устройства

На мобильных кнопка «наверх» требует особого подхода:

— Поднимите выше: bottom: 80px вместо 30px — чтобы не перекрывать панель навигации браузера и не мешать нажатию нижних элементов
— Увеличьте hit area: минимальная область нажатия 44×44px (стандарт Apple HIG). Наша кнопка 48px проходит, но можно сделать padding на wrapper'e
— На телефонах hover-эффекты бесполезны — уберите их через @media (hover: hover)
— Проверьте, что кнопка не перекрывает контент: на узких экранах можно сместить левее или уменьшить до 40px

Как добавить на WordPress

Способ 1. Плагин. Установите «WP Back to Top» или «Simple Back to Top» — настройте цвет, позицию, анимацию в админке. Минус: лишний плагин в системе.

Способ 2. Через кастомный код. Добавьте HTML в footer.php (перед </body>), CSS в style.css дочерней темы, JS — в отдельный файл и подключите через functions.php:

wp_enqueue_script('back-to-top', get_template_directory_uri() . '/js/back-to-top.js', [], null, true);

Параметр true в конце указывает, что скрипт грузится в footer — не блокирует рендеринг.

Как добавить на Tilda

В Tilda кнопку «наверх» можно сделать через Zero Block или через код на страницу:

— В настройках страницы → «HTML-код перед </body>» вставьте HTML кнопки и JS
— CSS добавьте в «HTML-код внутри <head>»
— Либо используйте готовый блок из Marketplace — есть несколько бесплатных вариантов

Кнопка «наверх» — это 30 строк кода, которые делают сайт удобнее. Добавьте её на все страницы с длинным контентом: статьи, каталоги, блоги, лендинги. Без неё пользователь устаёт скроллить и уходит.