Раньше, чтобы анимировать что-то при прокрутке, приходилось писать JavaScript. Слушать события scroll, вычислять позиции элементов, руками задавать стили. Это было сложно и работало неэффективно. Но в 2025 в CSS появилась нормальная нативная поддержка скролл-анимаций.

Частичная поддержка есть в Chrome 115+, Edge 115+ и Opera 117+, с флагами — в Firefox 110+. Ждём ещё Safari.

Внимание! Все примеры в этой статье работают только в Chrome 116+.

Что это значит?

Scroll-Driven Animations — это возможность привязать любую анимацию к прокрутке страницы или контейнера без JS. Работает напрямую в браузере, быстро и с минимальной болью.

Всё крутится вокруг двух новых концепций:

  1. Scroll Timeline — таймлайн, который двигается вместе с прокруткой.
  2. Animation Timeline — обычная CSS-анимация, но её прогресс контролируется не временем (@keyframes сами по себе), а прокруткой.

Иными словами — чем дальше пользователь проскроллил, тем дальше продвинулась анимация. На основе этой технологии уже делают интересные демки:

See the Pen scroll-driven maze (CPC — pure CSS) by Amit Sheen (@amit_sheen) on CodePen.

Самый простой вариант — перемещение элемента по скроллу в нашей интерактивной демонстрации:

Основные свойства Scroll-Driven Animations

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

animation-timeline

Это главное свойство. Оно говорит браузеру: «Привяжи мою анимацию не к времени, а к прокрутке». Можно указать три варианта значений:

  • scroll(root block) — привязка к всей странице вертикально.
  • scroll(self block) — привязка к самому контейнеру, где находится элемент.
  • или имя заранее созданной таймлайны (например, через view-timeline-name).

scroll-timeline

Позволяет явно описать таймлайн прокрутки, если нужно что-то нестандартное. На практике пока редко нужен, потому что scroll(root block) и scroll(self block) хватает в 90% случаев. Поддержка очень экспериментальная.

view-timeline-name

Это свойство создаёт таймлайн, который связан с появлением элемента в вьюпорте. Например:

view-timeline-name: --target-timeline;

Потом этот таймлайн можно использовать в animation-timeline.

view-timeline-axis

Указывает, по какой оси работает скроллинг:

  • block — вертикаль (стандартный скроллинг).
  • inline — горизонталь (если вдруг у вас сайт скроллится вбок).

view-timeline-inset

Позволяет настроить, где именно стартует и заканчивается расчёт прогресса таймлайна. Например, можно сказать, что анимация начнётся не сразу, а когда элемент войдёт в верхние 10% экрана:

view-timeline-inset: 10% 0%;

Примеры использования

Привязка к конкретному элементу

Можно привязать скролл-анимацию не к странице целиком, а к конкретному элементу. В этом случае у нас есть .scroller в качестве контейнера с прокруткой и .item — элемент, который будет постепенно появляться по мере скролла внутри .scroller.

Более продвинуто: Scroll-Linked Animations и View Progress

Ещё одна крутая возможность — отслеживать, насколько элемент виден на экране, и анимировать его соответственно. В этом случае view-timeline-name создаёт новый таймлайн, привязанный к видимости элемента. animation-timeline говорит: «используй именно этот таймлайн». И когда .target появляется в вьюпорте, он увеличивается в два раза по мере своего прохождения через экран.

target {
  width: 80px;
  height: 80px;
  background: green;
  view-timeline-name: --target-timeline;
  view-timeline-axis: block;
  animation: scaleUp 1s linear;
  animation-timeline: --target-timeline;
}
@keyframes scaleUp {
  from { transform: scale(1); }
  to { transform: scale(2); }
}

Пример:

Что выбрать?

В середине 2025 у есть несколько вариантов использования анимаций по скроллу:

  • Хотите анимацию по скроллу страницы → animation-timeline: scroll(root block).
  • Хотите анимацию по скроллу контейнера → animation-timeline: scroll(self block).
  • Хотите анимацию, завязанную на появлении элемента → нужно задать view-timeline-name и использовать его в animation-timeline.

И всё, у вас современная быстрая скролл-анимация без единой строчки JavaScript.