Прокрутка сайта состоит из нескольких независимых кусочков: плавный переход к разделу по клику в меню, кнопка «наверх», липкая шапка, блоки, проявляющиеся при пролистывании, и лента карточек, листающаяся вбок. Каждый делается парой строк CSS или одним точным заданием ИИ-помощнику. Ниже все пять случаев с кодом и промптами, а отдельно самая частая беда: страница едет вбок на телефоне.
Пять задач, которые прячутся за словом «прокрутка»
Сначала поймите, какая из задач ваша: они решаются по-разному и почти не связаны между собой.
- Плавный переход к разделу по клику в меню: это якоря.
- Кнопка «наверх», которая появляется после пролистанного экрана.
- Липкая шапка: меню остаётся сверху, пока страница листается.
- Появление блоков по мере прокрутки: текст и картинки мягко проявляются.
- Горизонтальная лента: карточки товаров или отзывов листаются вбок.
- И отдельно: страница уезжает вбок на телефоне сама. Это не эффект, а поломка вёрстки.
Почти все они делаются чистым CSS, без библиотек: скрипт нужен только кнопке «наверх». Если вы собираете страницу с ИИ, достаточно описать поведение словами. Заодно проверьте, что разделы вообще выделены: без этого якорям не за что зацепиться, набор блоков мы разбирали в материале про структуру разделов сайта.
Плавная прокрутка к разделу по клику в меню
Механика простая: у секции есть идентификатор, у пункта меню ссылка на него. По умолчанию браузер прыгает мгновенно, плавность включается одним свойством.
<nav>
<a href="#about">О нас</a>
<a href="#prices">Цены</a>
</nav>
<section id="about">…</section>
<section id="prices">…</section>
html {
scroll-behavior: smooth;
}
/* чтобы заголовок не прятался под липкой шапкой */
[id] {
scroll-margin-top: 90px;
}
Свойство scroll-behavior поддерживают все актуальные браузеры, последним его добавил Safari в версии 15.4 весной 2022 года (MDN). Свойство scroll-margin-top доступно ещё дольше, с апреля 2021 года (MDN), и решает вечную проблему, когда после клика заголовок раздела оказывается под шапкой.
Промпт: «Сделай пункты меню ссылками на разделы страницы: каждой секции добавь id, ссылкам href на этот id. Включи scroll-behavior: smooth у html и поставь scroll-margin-top 90px всем элементам с id, чтобы заголовок не уезжал под шапку. Скрипты не подключай, обойдись CSS».
Прокрутка это отделка, а сайт начинается раньше: с понятного порядка сборки страницы целиком.
Занять местоКнопка «наверх»
Здесь одним CSS не обойтись: кнопка должна появляться только после того, как человек пролистал страницу. Хватает нескольких строк скрипта.
const btn = document.querySelector('.to-top');
addEventListener('scroll', () => {
btn.classList.toggle('is-visible', scrollY > innerHeight);
}, { passive: true });
btn.addEventListener('click', () => {
scrollTo({ top: 0, behavior: 'smooth' });
});
Обратите внимание на { passive: true }: так браузер не ждёт скрипт и прокрутка остаётся гладкой. И пусть это будет настоящая кнопка, а не картинка с обработчиком, иначе она не сработает с клавиатуры.
Промпт: «Добавь кнопку «Наверх» в правом нижнем углу: fixed, отступ 16px, размер 48 на 48, доступна с клавиатуры. Скрыта по умолчанию, появляется после прокрутки на высоту экрана, по клику плавно возвращает в начало. Слушатель scroll обязательно passive, на мобильном учти safe-area снизу».
По теме: Как сделать окно на сайте в 2026: модальное, попап и согласие
Липкая шапка при прокрутке
Меню, которое остаётся сверху, делается свойством position: sticky без скриптов.
.site-header {
position: sticky;
top: 0;
z-index: 10;
background: #fff;
}
Две ловушки, на которых спотыкаются чаще всего. Первая: position: sticky перестаёт работать, если у любого родителя шапки стоит overflow: hidden или overflow-x: hidden. Вторая: фон шапки должен быть непрозрачным, иначе текст страницы будет просвечивать сквозь неё.
Липкая шапка на телефоне отъедает высоту у каждого экрана страницы. Держите её низкой, до 56 пикселей, и оставляйте в ней логотип и одну кнопку. Остальное меню прячьте под иконку.
Промпт: «Сделай шапку липкой: position: sticky, top: 0, непрозрачный фон, z-index выше контента, тонкая тень появляется только когда страница прокручена. Проверь, что ни у одного родителя шапки нет overflow: hidden. На экранах уже 900px высота шапки не больше 56 пикселей».
Появление блоков по мере прокрутки
Тот самый эффект, когда блок мягко всплывает при подходе к нему. В 2026 году есть два рабочих способа.
Чистый CSS. Анимации, привязанные к прокрутке, задаются свойством animation-timeline с функцией view(). Поддержка: Chrome и Edge с версии 115, Safari с версии 26, а в стабильном Firefox на июль 2026 этого нет (карточка возможности в Web Platform Features, свойство на MDN).
@media (prefers-reduced-motion: no-preference) {
.reveal {
animation: appear linear both;
animation-timeline: view();
animation-range: entry 0% cover 30%;
}
}
@keyframes appear {
from { opacity: 0; transform: translateY(24px); }
to { opacity: 1; transform: none; }
}
Важная деталь: в разметке блок остаётся видимым, прозрачность ему задаёт только анимация. Тогда в браузере без поддержки человек увидит обычную страницу без эффекта. Постоянная ошибка: прописать блоку opacity: 0 в обычных стилях. В Firefox такой блок останется невидимым навсегда.
Небольшой скрипт. Наблюдатель IntersectionObserver вешает блоку класс, когда тот попадает в зону видимости, дальше работает обычный CSS-переход. Работает во всех браузерах и стоит дешевле обработчика прокрутки.
В обоих случаях эффект оборачивайте в @media (prefers-reduced-motion: no-preference). Это системная настройка «уменьшить движение»: её включают люди, которых укачивает от анимаций (MDN).
Промпт: «Сделай мягкое появление секций при прокрутке: сдвиг на 24px и проявление за 0.4 секунды. Используй IntersectionObserver и CSS-переход, без библиотек анимации. Блоки в разметке видимы по умолчанию, скрывает их только скрипт. Весь эффект оберни в @media (prefers-reduced-motion: no-preference), анимируй только opacity и transform».
Последнее условие не придирка: opacity и transform браузер считает на видеокарте, а анимация ширины или отступов заставляет пересчитывать всю страницу на каждом кадре, и на телефоне это видно сразу.
Отдельный эффект собирается за пару минут, а вот целая страница, которую не стыдно показать заказчику, требует порядка действий. На бесплатном вебинаре по вайбкодингу его показывают на живом примере и отдают гайд в подарок.
Записаться на вебинарГоризонтальная прокрутка карточек
Лента отзывов или товаров, которая листается пальцем вбок, это обёртка с горизонтальной прокруткой. Чтобы карточки не замирали посередине, добавляется прилипание: CSS Scroll Snap доступен во всех браузерах с 2022 года (MDN).
.cards {
display: flex;
gap: 16px;
overflow-x: auto;
scroll-snap-type: x mandatory;
scroll-padding: 16px;
}
.cards > * {
flex: 0 0 80%;
scroll-snap-align: start;
}
Ширина карточки в 80% выбрана намеренно: край следующей виден, и человек понимает, что ленту можно листать. Мышью листать вбок неудобно, поэтому на компьютере добавьте стрелки, вызывающие scrollBy у контейнера. Главное: прокручиваться должен сам блок с карточками, а не страница, иначе получится беда из следующего раздела.
Промпт: «Собери горизонтальную ленту карточек: flex-контейнер с overflow-x: auto и scroll-snap-type: x mandatory, карточки шириной 80% экрана на телефоне и 320px на компьютере, scroll-snap-align: start. От 900px добавь кнопки-стрелки через scrollBy. Проследи, чтобы прокручивался только контейнер, а страница вбок не двигалась».
По теме: Лендинг с помощью нейросети в 2026: структура, промпты, публикация
Страница едет вбок на телефоне: как починить
Частая жалоба про прокрутку звучит наоборот: её не просили, а она появилась. Причина всегда одна: какой-то элемент шире экрана. Искать наугад бессмысленно, действуйте по шагам.
- Воспроизведите проблему. Сузьте окно браузера на компьютере до 320 и 375 пикселей: почти всегда беда видна уже там.
- Убедитесь, что переполнение есть. В консоли сравните document.documentElement.scrollWidth и clientWidth. Первое больше, значит страница шире экрана.
- Найдите виновника скриптом ниже: он выведет элементы, чей край выходит за границу страницы.
- Почините причину, а не симптом. Виновников обычно один-два, и лечатся они точечно.
const limit = document.documentElement.clientWidth;
document.querySelectorAll('*').forEach(el => {
const box = el.getBoundingClientRect();
if (box.right > limit + 1 || box.left < -1) console.log(el);
});
Кто обычно оказывается в этом списке:
- Блок с шириной
100vw. Эта единица не учитывает вертикальную полосу прокрутки, поэтому блок получается шире страницы (разбор в Smashing Magazine). Помогаетwidth: 100%. - Строка элементов через
display: flexбезflex-wrap: wrap: на узком экране она отказывается переноситься. - Длинная ссылка или команда без пробелов. Лечится
overflow-wrap: break-wordу текстовых блоков. - Таблица или блок кода: их надо прокручивать внутри себя через
overflow-x: auto. - Картинка или видео без
max-width: 100%, отрицательные отступы у секции, декор, вынесенный за край.
Соблазн поставить overflow-x: hidden на body велик, но это заклейка: полоса исчезнет, а часть содержимого останется за краем экрана, плюс иногда перестаёт работать липкая шапка. Сначала найдите элемент. Проверять результат надо на реальной ширине телефона, об этом подробнее в статье про мобильную версию сайта.
Промпт: «На ширине 320 и 375 пикселей страница прокручивается вбок. Найди элементы шире вьюпорта и почини причину: замени 100vw на 100%, добавь flex-wrap строкам, overflow-wrap: break-word текстам, max-width: 100% картинкам, таблицы и блоки кода сделай прокручиваемыми внутри себя. overflow-x: hidden у body не ставь. В конце покажи, что scrollWidth равен clientWidth».
Мера: когда прокрутка начинает мешать
Эффектами прокрутки легко переборщить. Каждая анимация это работа процессора на каждом кадре, а телефон у читателя обычно слабее вашего компьютера. Разумный набор для обычного сайта: плавные якоря, липкая шапка и появление блоков не больше чем у трети секций.
- Не перехватывайте прокрутку: когда колесо мыши листает не страницу, а внутренний слайдер, привычное поведение ломается, и особенно это раздражает на тачпаде.
- Откажитесь от параллакса на фоновых картинках: самый дорогой по нагрузке эффект, на телефонах дёргается почти всегда.
- Не привязывайте к прокрутке ничего важного: если текст показывается только после анимации, его рискует не увидеть и поисковый робот, и человек с включённой настройкой «уменьшить движение».
Скорость проверяйте после того, как эффекты добавлены: за этим удобно следить по весу страницы, как мы разбирали отдельно. А если вы только знакомитесь с самим CSS, свойства из этой статьи удобно потрогать на маленькой учебной странице, как в разборе сайта на HTML и CSS.
Частые вопросы
Можно ли сделать плавную прокрутку без кода, в конструкторе?
Да. В блочных конструкторах якоря настраиваются в свойствах кнопки: секции задаётся идентификатор, кнопке выбирается переход к нему. Липкая шапка и появление блоков там тоже есть готовыми настройками. Ограничение в другом: тонко управлять поведением, например отступом под шапку, там почти нельзя.
Почему плавная прокрутка не работает?
Три причины по частоте. Свойство поставили не на тот элемент: оно нужно на html или на том контейнере, который реально прокручивается. У страницы своя обёртка с прокруткой вместо обычной страницы. И третья, неочевидная: у человека включено «уменьшить движение», тогда браузер намеренно прокручивает мгновенно.
Нужна ли библиотека для плавной прокрутки?
Для перечисленных задач нет. Библиотеки, подменяющие нативную прокрутку своей, добавляют вес и часто ломают поведение на тачскринах. Они оправданы разве что в сложных промо-страницах с раскадровкой.
Как сделать полоску прогресса чтения сверху?
Это та же анимация по таймлайну прокрутки, только с функцией scroll() вместо view(): полоска растягивается по мере продвижения по странице. Там, где нужна поддержка Firefox, тот же результат даёт короткий скрипт, считающий долю прокрутки.
Прокрутка это одна деталь. Если хочется собрать сайт целиком и понимать, что делать с каждым блоком, посмотрите бесплатный воркшоп по созданию сайтов с ИИ: там страницу собирают от идеи до публикации.
Смотреть воркшоп