Реалізація CSS Scroll-Driven Animations на сайті

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Пропоновані послуги
Показано 1 з 1 послугУсі 2065 послуг
Реалізація CSS Scroll-Driven Animations на сайті
Середня
~2-3 робочих дні
Часті питання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    874
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851

Реалізація CSS Scroll-Driven Animations на сайті

CSS Scroll-Driven Animations — нативний браузерний API, що дозволяє прив'язувати CSS @keyframes до позиції скролу без JavaScript. З'явився в Chrome 115, Firefox 110 (частково), Safari — поки без підтримки (2025). Для виробничого використання потрібен полфіл. Головна перевага перед JS-рішеннями: анімації виконуються на compositor thread, не блокують основний потік.

Базова концепція

Два типи timeline:

  • scroll() — прив'язка до позиції скролу скролл-контейнера
  • view() — прив'язка до видимості елемента у viewport (аналог IntersectionObserver)
/* Прогрес-бар читання сторінки */
@keyframes grow-bar {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}

.reading-progress {
  position: fixed;
  top: 0; left: 0;
  width: 100%; height: 3px;
  background: #3b82f6;
  transform-origin: left;

  animation: grow-bar linear;
  animation-timeline: scroll(root);          /* прив'язка до root scroll */
  animation-fill-mode: both;
}

view(): анімації при появленні елементів

/* Появлення карточок при скролі */
@keyframes fade-up {
  from {
    opacity: 0;
    transform: translateY(40px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.card {
  animation: fade-up ease-out both;
  animation-timeline: view();

  /* Діапазон: від моменту входу до 40% видимості */
  animation-range: entry 0% entry 40%;
}

/* Паралакс для зображень */
@keyframes parallax-img {
  from { object-position: 50% 30%; }
  to   { object-position: 50% 70%; }
}

.hero-image {
  animation: parallax-img linear both;
  animation-timeline: view();
  animation-range: contain;
}

Названі timeline через scroll-timeline

Коли потрібно керувати анімацією з іншого елемента:

/* Батьківський контейнер створює названу timeline */
.scroll-container {
  overflow-y: scroll;
  scroll-timeline: --my-scroll block;
  height: 100vh;
}

/* Дочірній елемент використовує цю timeline */
.animated-sidebar {
  animation: slide-in linear both;
  animation-timeline: --my-scroll;
  animation-range: 0% 30%;
}

@keyframes slide-in {
  from { transform: translateX(-100%); }
  to   { transform: translateX(0); }
}

Складний приклад: трансформація sticky header

/* Хедер змінюється при скролі */
@keyframes header-shrink {
  from {
    padding: 24px 40px;
    background: transparent;
    backdrop-filter: none;
  }
  to {
    padding: 12px 40px;
    background: rgba(255, 255, 255, 0.9);
    backdrop-filter: blur(12px);
  }
}

.site-header {
  position: sticky;
  top: 0;
  animation: header-shrink linear both;
  animation-timeline: scroll(root);
  animation-range: 0px 200px; /* перші 200px скролу */
}

Полфіл для Safari

npm install @scroll-timeline-polyfill/scroll-timeline
// app/layout.tsx (Next.js) або index.html script
async function loadScrollTimelinePolyfill() {
  const isSupported = CSS.supports('animation-timeline: scroll()')
  if (!isSupported) {
    await import('@scroll-timeline-polyfill/scroll-timeline')
  }
}

loadScrollTimelinePolyfill()

Альтернатива — умовний JS-фоллбек через IntersectionObserver для критичних анімацій.

Прогресивне поліпшення: @supports

/* Базовий стиль для всіх браузерів */
.animated-section {
  opacity: 0;
  transform: translateY(30px);
  transition: opacity 0.5s, transform 0.5s;
}

.animated-section.visible {
  opacity: 1;
  transform: translateY(0);
}

/* Scroll-Driven для браузерів, що підтримують */
@supports (animation-timeline: scroll()) {
  .animated-section {
    opacity: 1;
    transform: none;
    transition: none;

    animation: fade-up ease-out both;
    animation-timeline: view();
    animation-range: entry 0% entry 50%;
  }
}

JavaScript фоллбек через IntersectionObserver:

// utils/scroll-animation-fallback.ts
export function initScrollAnimationFallback() {
  // Пропускаємо якщо нативна підтримка є
  if (CSS.supports('animation-timeline: scroll()')) return

  const observer = new IntersectionObserver(
    entries => {
      entries.forEach(entry => {
        if (entry.isIntersecting) {
          entry.target.classList.add('visible')
          observer.unobserve(entry.target)
        }
      })
    },
    { rootMargin: '-10% 0px -10% 0px', threshold: 0.1 }
  )

  document.querySelectorAll('.animated-section').forEach(el => {
    observer.observe(el)
  })
}

animation-range докладніше

/* Названі ключові слова для view() */

/* entry: елемент входить у scroll-port */
animation-range: entry 0% entry 100%;

/* exit: елемент виходить */
animation-range: exit 0% exit 100%;

/* contain: поки елемент повністю видимий */
animation-range: contain;

/* cover: від початку входу до кінця виходу */
animation-range: cover 0% cover 100%;

/* Комбінований: вхід + вихід */
.element {
  animation: appear linear both;
  animation-timeline: view();
  animation-range: entry 10% exit 90%;
}

Типові терміни

Прогрес-бар читання + 3–4 fade-анімації при скролі — 4–6 годин. Повноцінна система з полфілом, @supports, JS-фоллбеком, тестами в Safari і мобільних браузерах — 2–3 робочих дні.