16 июня 2025 г. (изменено: 17 июня 2025 г.)

Канал: @cherkashindev

1 171

📈 Анимации по скролу — Scroll Progress Timelines

У меня вообще не очень дела с CSS анимациями, но я наконец-то дочитал статью An Introduction To CSS Scroll-Driven Animations и решил рассказать, что такое Scroll Progress Timelines, и показать свою небольшую демку.

Обязательно откройте статью — там крутые примеры! Только посмотрите на эту шикарную демку с сардинами с шпротами сардинами 🐟.

Если вы писали простейшие анимации, вы знаете, что обычно нужно прописать длительность цикла анимации:

 
.element { 
 animation-duration: 2s; 
}

Scroll Progress Timelines позволяют вместо времени использовать позицию скроллбара элемента. То есть, вы скроллите страницу вниз — анимация воспроизводится вперёд, скроллите вверх — прокручивается назад 🔁

Самый очевидный пример — прогресс чтения статьи, который растёт, пока вы пролистываете страницу.

Для этого достаточно указать:

 
animation-timeline: scroll(<scroller> <axis>);

У функции scroll есть два необязательных параметра:

  • scroller — указывает контейнер прокрутки: nearest, root или self
    • если этих значений недостаточно, смотрите в сторону scroll-timeline-name и timeline-scope — они позволяют привязать анимацию к скроллбару любого элемента.
  • axis — направление прокрутки:
    • block — по оси y (вертикально)
    • inline — по оси x (горизонтально)

Ещё с помощью animation-range можно управлять, в какой момент начинается и заканчивается анимация.

Возвращаясь к примеру с прогрессбаром чтения — мы явно хотим, чтобы анимация закончилась у секции с футером высотой в 500px:

 
animation-range: 0% calc(100% - 500px);

**👉 **Моя демка

Я решил накидать свою демку и попробовал реализовать анимацию прокрутки к историям в Телеграме. Если кратко:

  • анимация работает только на первых 100px прокрутки
    • тут помог animation-range: 0 100px
  • список сообщений смещается вниз на 100px по мере прокрутки, чтобы не мешать показу историй
 
@keyframes scrollAnimation {
 from {
  margin-top: 0;
 }
 
 to {
  margin-top: var(--stories-height);
 }
}
 
.contacts-list { 
 /* ... */
    animation: scrollAnimation linear;
 animation-timeline: scroll();
 animation-range: 0 var(--stories-height);
 animation-fill-mode: both;
}
  • Чтобы анимация не застывала на промежуточном этапе, используется scroll-snap-type: y proximity. Так как секция с историями position: sticky, а список сообщений перемещается по анимации, то их использовать не получится. Но Claude подсказал мне, что можно использовать псевдо-элементы со свойстов scroll-snap-align: start, где они абсолютно позиционированы
    • первый — top: 0
    • второй — top: 100px
  • Всё написано на CSS, кроме одного: позиция скролла устанавливается через JS, чтобы истории были свернуты — как в самом Телеграме. Если знаете как это сделать через CSS — расскажите 🙏.

🚨 В общем переходите и поиграйтесь тут

Ещё про анимации на сайте доки:

И вот ещё одна демка с тенями прокрутки

Расскажите, вам часто приходится применять что-то подобное на реальных проектах? Я вот пока ни разу не применял, но знаю, где это могло бы мне помочь лет 6 назад 😅.

🔥 12 4 👍 3