Знакомство с анимацией CSS при прокрутке: прокрутка и просмотр временных шкал прогресса
Прошло 10 лет с тех пор, как в спецификации были представлены анимации, управляемые прокруткой, и после пяти лет разработки мы наконец-то начинаем видеть их на веб-сайтах. Есть анимации с прокруткой и игры-лабиринты, а также анимации с прокруткой и 3D-вращение с прокруткой… но что именно здесь нового? Не то чтобы мы раньше не видели анимаций с прокруткой, но то, что мы имеем сейчас, не требует ни JavaScript, ни зависимостей, ни библиотек — только чистый CSS. И если этого недостаточно, то эти анимации запускаются в основном потоке, обеспечивая плавную работу с высокой производительностью и ускорением на графическом процессоре.
С декабря 2024 года вы можете безопасно использовать анимацию при прокрутке в Chrome. Firefox тоже поддерживает её, но вам нужно будет включить флаг. Safari? Пока нет, но не волнуйтесь — вы всё равно можете обеспечить бесперебойную работу во всех браузерах с помощью полифилла. Просто имейте в виду, что для добавления полифилла требуется библиотека JavaScript, поэтому вы не получите такого же повышения производительности.
В этой статье мы рассмотрим последнюю опубликованную W3C версию и изучим два типа временных шкал с прокруткой — временные шкалы с прокруткой и временные шкалы с просмотром. К концу статьи я надеюсь, что вы будете знакомы с обеими временными шкалами и сможете не только отличать их друг от друга, но и уверенно использовать их в своей работе.
Примечание: Все демонстрации в этой статье работают только в Chrome 116 или более поздних версиях на момент написания статьи.
Прокрутите Временную шкалу прогресса
Временная шкала прогресса прокрутки связывает временную шкалу анимации с положением прокрутки контейнера прокрутки по определённой оси. Таким образом, анимация напрямую связана с прокруткой. По мере прокрутки вперёд анимация тоже прокручивается. Я буду называть ихscroll-timeline
анимациями, а не временными шкалами прогресса прокрутки.
Точно так же, как у нас есть два типа анимации при прокрутке, у нас есть два типаscroll-timeline
-анимации:анонимные временные шкалыиименованные временные шкалы.
Анонимныйscroll-timeline
Давайте начнём с классического примера: создадим индикатор выполнения прокрутки в верхней части поста в блоге, чтобы отслеживать ход чтения.
Пример временной шкалы хода прокрутки - перед анимацией -прокрутка временной шкалы
В этом примере есть элемент<div>
с идентификатором «progress». В конце файла CSS вы увидите, что у него есть цвет фона, заданная ширина и высота, и он закреплён в верхней части страницы. Также есть анимация, которая масштабирует его от0
до1
по оси X — довольно стандартная, если вы знакомы с CSS-анимацией!
Вот соответствующая часть стилей:
#progress {
/* ... */
animation: progressBar 1s linear;
}
@keyframes progressBar {
from { transform: scaleX(0); }
}
АнимацияprogressBar
запускается один раз и длится одну секунду с линейной функцией тайминга. Чтобы связать эту анимацию с прокруткой, достаточно одной строки в CSS:
animation-timeline: scroll();
Не нужно указывать секунды для продолжительности — время будет определяться поведением прокрутки. И всё! Вы только что создали свою первую анимацию, управляемую прокруткой! Обратите внимание, что направление анимации напрямую связано с направлением прокрутки: при прокрутке вниз индикатор выполнения становится шире, а при прокрутке вверх — уже.
Пример временной шкалы хода прокрутки - анимация-прокрутка временной шкалы
scroll-timeline
Параметры объекта
В анимацииscroll-timeline
функцияscroll()
используется внутри свойстваanimation-timeline
. Она принимает только два параметра:<scroller>
и<axis>
.
<scroller>
относится к контейнеру прокрутки, который может быть задан какnearest
(по умолчанию),root
илиself
.<axis>
относится к оси прокрутки, которая может бытьblock
(по умолчанию),inline
,x
, илиy
.
В приведённом выше примере с чтением мы не указывали ни один из этих параметров, потому что использовали значения по умолчанию. Но мы могли бы добиться того же результата с помощью:
animation-timeline: scroll(nearest block);
Здесьnearest
контейнер прокрутки — это корневая прокрутка HTML-элемента. Таким образом, мы могли бы также написать это следующим образом:
animation-timeline: scroll(root block);
Осьblock
подтверждает, что прокрутка происходит сверху вниз в режиме письма слева направо. Если страница имеет широкую горизонтальную прокрутку и мы хотим анимировать по этой оси, мы можем использовать значенияinline
илиx
(в зависимости от того, хотим ли мы, чтобы направление прокрутки всегда было слева направо или менялось в зависимости от режима письма).
Мы рассмотримself
иinline
на более сложных примерах позже, но лучший способ научиться — поэкспериментировать со всеми комбинациями, иэтот инструмент позволяет вам это сделать. Прежде чем мы перейдём к следующему свойству, связанному с временными шкалами прокрутки, потратьте несколько минут на изучение.
scroll-timeline
Параметры объекта
В анимацииscroll-timeline
функцияscroll()
используется внутри свойстваanimation-timeline
. Она принимает только два параметра:<scroller>
и<axis>
.
<scroller>
относится к контейнеру прокрутки, который может быть задан какnearest
(по умолчанию),root
илиself
.<axis>
относится к оси прокрутки, которая может бытьblock
(по умолчанию),inline
,x
, илиy
.
В приведённом выше примере с чтением мы не указывали ни один из этих параметров, потому что использовали значения по умолчанию. Но мы могли бы добиться того же результата с помощью:
animation-timeline: scroll(nearest block);
Здесьnearest
контейнер прокрутки — это корневая прокрутка HTML-элемента. Таким образом, мы могли бы также написать это следующим образом:
animation-timeline: scroll(root block);
Осьblock
подтверждает, что прокрутка происходит сверху вниз в режиме письма слева направо. Если страница имеет широкую горизонтальную прокрутку и мы хотим анимировать по этой оси, мы можем использовать значенияinline
илиx
(в зависимости от того, хотим ли мы, чтобы направление прокрутки всегда было слева направо или менялось в зависимости от режима письма).
Мы рассмотримself
иinline
на более сложных примерах позже, но лучший способ научиться — поэкспериментировать со всеми комбинациями.
animation-range
Свойство
animation-range
дляscroll-timeline
определяет, какая часть прокручиваемого содержимого управляет началом и окончанием анимации в зависимости от положения прокрутки. Это позволяет вам решать, когда анимация начинается или заканчивается при прокрутке контейнера.
По умолчаниюanimation-range
устанавливается в значениеnormal
, что является сокращением для следующего:
animation-range-start: normal;
animation-range-end: normal;
Это переводится как0%
(start
) и100%
(end
) вscroll-timeline
анимации:
animation-range: normal normal;
... что является таким же, как:
animation-range: 0% 100%;
Вы можете указать любыеединицы измерения длины в CSSили дажевычисления. Например, предположим, что у меня есть нижний колонтитул высотой500px
. Он заполнен баннерами, рекламой и связанными с ними публикациями. Я не хочу, чтобы индикатор выполнения прокрутки включал что-либо из этого в процесс чтения. Я хочу, чтобы анимация начиналась сверху и заканчивалась500px
до нижней части. Вот и всё:
animation-range: 0% calc(100% - 500px);
Пример временной шкалы прокрутки — animation-timeline, animation-range
Вот так просто мы рассмотрели ключевые свойстваscroll-timeline
анимаций. Готовы сделать следующий шаг?
Названныйscroll-timeline
Допустим, я хочу использовать положение прокрутки другого контейнера прокрутки для той же анимации. Свойствоscroll-timeline-name
позволяет указать, с каким контейнером прокрутки должна быть связана анимация прокрутки. Вы указываете имя (например,--my-scroll-timeline
), которое соответствует контейнеру прокрутки, который вы хотите использовать. Этот контейнер будет управлять ходом анимации по мере прокрутки пользователем.
Далее нам нужно определить ось прокрутки для этого нового контейнера с помощьюscroll-timeline-axis
, которая сообщает анимации, какая ось будет запускать движение. Вот как это выглядит в коде:
.my-class {
/* This is my new scroll-container */
scroll-timeline-name: --my-custom-name;
scroll-timeline-axis: inline;
}
Если вы опустите ось, то будет использовано значениеblock
по умолчанию. Однако вы также можете использовать сокращённое свойствоscroll-timeline
для объединения имени и оси в одном объявлении:
.my-class {
/* Shorthand for scroll-container with axis */
scroll-timeline: --my-custom-name inline;
}
Я думаю, что всё это проще понять на практическом примере. Вот тот же индикатор выполнения, с которым мы работали, но с встроенной прокруткой (то есть по оси X):
Смотрите именованную временную шкалу прогресса прокрутки
У нас запущены две анимации:
- Индикатор выполнения становится шире при прокрутке в направлении строки.
- Цвет фона контейнера меняется по мере дальнейшей прокрутки.
Структура HTML выглядит следующим образом:
<div class="gallery">
<div class="gallery-scroll-container">
<div class="gallery-progress" role="progressbar" aria-label="progress"></div>
<img src="image1.svg" alt="Alt text" draggable="false" width="500">
<img src="image2.svg" alt="Alt text" draggable="false" width="500">
<img src="image3.svg" alt="Alt text" draggable="false" width="500">
</div>
</div>
В этом случаеgallery-scroll-container
имеет горизонтальную прокрутку и меняет цвет фона при прокрутке. Обычно для этого можно просто использоватьanimation-timeline: scroll(self inline)
. Однако мы также хотим, чтобы элементgallery-progress
использовал ту же прокрутку для своей анимации.
Элементgallery-progress
является первым внутриgallery-scroll-container
, и мы потеряем его при прокрутке, если он не будет расположен абсолютно. Но когда мы это делаем, элемент больше не занимает место в обычном потоке документа, и это влияет на его взаимодействие с родительским элементом и другими элементами. Нам нужно указать, к какому контейнеру прокрутки мы хотим его привязать.
Вот где пригодится присвоение имени контейнеру прокрутки. Указавgallery-scroll-container
ascroll-timeline-name
иscroll-timeline-axis
, мы можем гарантировать синхронизацию обеих анимаций с одним и тем же свитком.:
.gallery-scroll-container {
/* ... */
animation: bg steps(1);
scroll-timeline: --scroller inline;
}
И использует ли эту прокрутку для определения своей собственнойanimation-timeline
:
.gallery-scroll-container {
/* ... */
animation: bg steps(1);
scroll-timeline: --scroller inline;
animation-timeline: --scroller;
}
Теперь мы можем масштабировать это название для индикатора выполнения, который использует другую анимацию, но реагирует на ту же прокрутку:
.gallery-progress {
/* ... */
animation: progressBar linear;
animation-timeline: --scroller;
}
Это позволяет обеим анимациям (растущей полосе загрузки и изменению цвета фона) вести себя одинаково при прокрутке, даже если это отдельные элементы и анимации.
timeline-scope
Свойство
Что произойдёт, если мы захотим анимировать что-то в зависимости от положения прокрутки элемента-брата или даже более высокого предка? Здесь в игру вступает свойствоtimeline-scope
. Оно позволяет нам расширить область действияscroll-timeline
. Значениеtimeline-scope
. должно быть пользовательским идентификатором, который снова является тире-идентификатором.
Давайте проиллюстрируем это на новом примере. На этот раз при прокрутке в одном контейнере запускается анимация в другом контейнере:
Анимация с прокруткой - временная шкала-область действия
Мы можем воспроизводить анимацию изображения при прокрутке текстового контейнера, потому что они являются братьями и сёстрами в структуре HTML:
<div class="main-container">
<div class="sardinas-container">
<img ...>
</div>
<div class="scroll-container">
<p>Long text...</p>
</div>
</div>
Здесь только.scroll-container
имеет прокручиваемый контент, поэтому давайте начнём с его названия:
.scroll-container {
/* ... */
overflow-y: scroll;
scroll-timeline: --containerText;
}
Обратите внимание, что я не указал ось прокрутки, так как по умолчанию используетсяblock
(прокрутка по вертикали), и это то значение, которое мне нужно.
Давайте перейдём к изображению внутриsardinas-container
. Мы хотим, чтобы это изображение анимировалось при прокруткеscroll-container
. Я добавилscroll-timeline-name
к егоanimation-timeline
свойству:
.sardinas-container img {
/* ... */
animation: moveUp steps(6) both;
animation-timeline: --containerText;
}
Однако на этом этапе анимация всё равно не будет работать, потому чтоscroll-container
не связан напрямую с изображениями. Чтобы это работало, нам нужно расширитьscroll-timeline-name
так, чтобы он стал доступным. Это делается путём добавленияtimeline-scope
к родительскому элементу (или более высокому предку), общему для обоих элементов:
.main-container {
/* ... */
timeline-scope: --containerText;
}
При такой настройке прокруткаscroll-container
теперь будет управлять анимацией изображения внутриsardinas-container
!
Теперь, когда мы разобрались с использованиемtimeline-scope
, мы готовы перейти к следующему типу анимации при прокрутке, где будут применяться те же свойства, но с небольшими отличиями в поведении.
Просмотр Графиков выполнения
Мы только что рассмотрелианимацию при прокрутке. Это первый тип анимации при прокрутке из двух. Далее мы обратимся канимации при просмотре. Между ними много общего! Но они достаточно отличаются друг от друга, чтобы заслуживать отдельного раздела, в котором мы рассмотрим, как они работают. Я буду называть ихview-timeline
анимациями, а не анимацией при просмотре, так как они связаны сview()
функцией.
Временная шкала прогресса просмотра— это второй тип анимации при прокрутке, на который мы обращаем внимание. Она отслеживает элемент, когда он входит в область прокрутки (видимую область прокручиваемого контента) или выходит из неё. Такое поведение очень похоже нато, какIntersectionObserver
работает в JavaScript, но может быть реализовано полностью в CSS.
У нас есть анонимные и именованные временные шкалы прогресса просмотра, а также анонимные и именованные анимации прогресса прокрутки. Давайте разберёмся с ними.
Временная шкала Анонимного просмотра
Вот простой пример, который поможет нам понять основную идею анонимных временных шкал. Обратите внимание, как изображение появляется при прокрутке вниз до определённой точки на странице:
Смотрите анимацию View Timeline — view()
Допустим, мы хотим анимировать изображение, которое появляется в области прокрутки. Непрозрачность изображения будет меняться от0
до1
. Вот как можно написать эту же анимацию в классическом CSS с помощью@keyframes
:
img {
/* ... */
animation: fadeIn 1s;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
Это здорово, но мы хотим, чтобы изображениеfadeIn
появлялось, когда оно в поле зрения. В противном случае анимация будет похожа на дерево, которое падает в лесу, и никто не видит этого... была ли вообще анимация? Мы никогда не узнаем!
У нас есть функцияview()
для создания анимации прогресса просмотра с помощью одной строки CSS:
img {
/* ... */
animation: fadeIn;
animation-timeline: view();
}
И обратите внимание, что нам больше не нужно объявлятьanimation-duration
как в классическом CSS. Анимация больше не привязана ко времени, а привязана к пространству. Анимация запускается, когда изображение становится видимым в области прокрутки.
Просмотр параметров временной шкалы
Как и свойствоscroll-timeline
, свойствоview-timeline
принимает параметры, которые позволяют выполнять более тонкую настройку:
animation-timeline: view( );
<inset>
Управляет началом и окончанием анимации в зависимости от видимости элемента в области прокрутки. Определяет расстояние между краями области прокрутки и отслеживаемым элементом. Значение по умолчанию —auto
, но также можно использовать процентное значение длины, а также начальное и конечное значения.<axis>
Это похоже на параметр оси прокрутки. Он определяет, к какой оси (горизонтальной или вертикальной) привязана анимация. По умолчанию используетсяblock
, что означает отслеживание вертикального движения. Вы также можете использоватьinline
для отслеживания горизонтального движения или простоx
илиy
.
Вот пример, в котором используютсяinset
иaxis
для настройки времени и способа запуска анимации:
img {
animation-timeline: view(20% block);
}
В данном случае:
- Анимация начинается, когда изображение занимает 20% видимой области прокрутки.
- Анимация запускается вертикальной прокруткой (
block
ось).
Эффект параллакса
С помощью функцииview()
также легко создавать эффекты параллакса, просто настраивая свойства анимации. Например, вы можете заставить элемент двигаться или масштабироваться при входе в область прокрутки без использования JavaScript:
img {
animation: parallaxMove 1s;
animation-timeline: view();
}
@keyframes parallaxMove {
to { transform: translateY(-50px); }
}
Это невероятно упрощает создание динамичных и привлекательных анимаций прокрутки с помощью всего нескольких строк CSS.
Эффект параллакса с анимацией, управляемой прокруткой CSS - view()
animation-range
Свойство
Использование свойства CSSanimation-range
с временными шкалами просмотра определяет, какая часть видимости элемента в области просмотра определяет начальную и конечную точки анимации. Это можно использовать для точной настройки начала и окончания анимации в зависимости от видимости элемента в области просмотра.
Хотя значение по умолчанию равноnormal
, в таймлайнах просмотра оно означает отслеживание полной видимости элемента с момента его появления в области прокрутки до полного исчезновения. Это отображается следующим образом:
animation-range: normal normal;
/* Equivalent to */
animation-range: cover 0% cover 100%;
Или, проще говоря:
animation-range: cover;
Существует шесть возможных значений илиtimeline-range-names
:
cover
Отслеживает полную видимость элемента с момента его появления в области прокрутки до момента, когда он полностью покидает её.contain
Отслеживает, когда элемент полностью отображается в области прокрутки, с момента, когда он полностью отображается, до момента, когда он перестаёт отображаться.entry
Отслеживает элемент с момента его появления в области прокрутки до полного заполнения области.exit
Отслеживает элемент с момента его появления, пока он не выйдет за пределы области прокрутки.entry-crossing
Отслеживает элемент, когда он пересекает начальную границу области прокрутки, от начала до полного пересечения.exit-crossing
Отслеживает элемент, когда он пересекает край области прокрутки, от начала до полного пересечения.
Вы можете комбинировать различныеtimeline-range-names
для управления начальной и конечной точками диапазона анимации. Например, вы можете сделать так, чтобы анимация начиналась, когда элемент попадает в область прокрутки, и заканчивалась, когда он из неё выходит:
animation-range: entry exit;
Вы также можете комбинировать эти значения с процентами, чтобы задать более сложное поведение, например, начать анимацию в середине перехода элемента и завершить её в середине его выхода:
animation-range: entry 50% exit 50%;
Изучать все эти значения и комбинации лучше всего в интерактивном режиме.
Дальность поражения цели Внутри@keyframes
Одной из мощных функцийtimeline-range-names
является возможность использовать их внутри@keyframes
:
Целевой диапазон внутри @keyframes — view-timeline, timeline-range-name
В этой демо-версии происходят две разные анимации:
slideIn
Когда элемент попадает в область прокрутки, он масштабируется и становится видимым.slideOut
Когда элемент уходит, он уменьшается в размерах и исчезает.
@keyframes slideIn {
from {
transform: scale(.8) translateY(100px);
opacity: 0;
}
to {
transform: scale(1) translateY(0);
opacity: 1;
}
}
@keyframes slideOut {
from {
transform: scale(1) translateY(0);
opacity: 1;
}
to {
transform: scale(.8) translateY(-100px);
opacity: 0
}
}
Новым является то, что теперь мы можем объединить эти две анимации с помощьюentry
иexit
timeline-range-names
, упростив их до одной анимации, которая подходит для обоих случаев:
@keyframes slideInOut {
/* Animation for when the element enters the scrollport */
entry 0% {
transform: scale(.8) translateY(100px);
opacity: 0;
}
entry 100% {
transform: scale(1) translateY(0);
opacity: 1;
}
/* Animation for when the element exits the scrollport */
exit 0% {
transform: scale(1) translateY(0);
opacity: 1;
}
exit 100% {
transform: scale(.8) translateY(-100px);
opacity: 0;
}
}
entry 0%
Определяет состояние элемента в начале его перемещения в область прокрутки (уменьшен в размере и прозрачен).entry 100%
Определяет состояние, когда элемент полностью вошёл в область прокрутки (полностью виден и увеличен в размере).exit 0%
Начинает отслеживать элемент, когда он начинает выходить за пределы области прокрутки (видно и увеличено).exit 100%
Определяет состояние, когда элемент полностью покинул область прокрутки (уменьшен в размере и прозрачен).
Такой подход позволяет плавно анимировать поведение элемента при его входе в область прокрутки и выходе из неё в рамках одного блока@keyframes
.
Названныйview-timeline
Иtimeline-scope
Концепция использованияview-timeline
с именованными временными шкалами и их связывания с различными элементами может значительно расширить возможности анимации при прокрутке. В данном случае мы связываем анимацию изображений при прокрутке с анимацией несвязанных абзацев в структуре DOM с помощьюименованногоview-timeline
иtimeline-scope
.
Свойствоview-timeline
работает так же, как и свойствоscroll-timeline
. Это сокращённая запись для объявления свойствview-timeline-name
иview-timeline-axis
в одной строке. Однако отличие отscroll-timeline
заключается в том, что мы можем связать анимацию элемента с моментом, когда связанные элементы попадают в область прокрутки. Я взял предыдущую демонстрацию и добавил анимацию к абзацам, чтобы вы могли увидеть, как меняется непрозрачность текста при прокрутке изображений слева:
Смотрите временную шкалу, область временной шкалы
Этот пример выглядит немного громоздким, но мне было трудно найти более подходящий для демонстрации его возможностей. Каждому изображению в контейнере с вертикальной прокруткой присваивается имяview-timeline
с уникальным идентификатором:
.vertical-scroll-container img:nth-of-type(1) { view-timeline: --one; }
.vertical-scroll-container img:nth-of-type(2) { view-timeline: --two; }
.vertical-scroll-container img:nth-of-type(3) { view-timeline: --three; }
.vertical-scroll-container img:nth-of-type(4) { view-timeline: --four; }
Это позволяет присвоить временной шкале прокрутки каждого изображения собственное имя, например--one
для первого изображения,--two
для второго и так далее.
Далее мы подключаем анимацию абзацев к именованным временным шкалам изображений. Соответствующий абзац должен анимироваться, когда изображения попадают в область прокрутки:
.vertical-text p:nth-of-type(1) { animation-timeline: --one; }
.vertical-text p:nth-of-type(2) { animation-timeline: --two; }
.vertical-text p:nth-of-type(3) { animation-timeline: --three; }
.vertical-text p:nth-of-type(4) { animation-timeline: --four; }
Однако, поскольку изображения и абзацы не связаны напрямую в DOM, нам нужно объявитьtimeline-scope
для их общего предка. Это гарантирует, что на именованные временные шкалы (--one
,--two
и так далее) можно ссылаться и использовать их совместно между элементами:
.porto {
/* ... */
timeline-scope: --one, --two, --three, --four;
}
Объявивtimeline-scope
со всеми именованными временными шкалами (--one
,—two
,--three
,--four
), и изображения, и абзацы могут участвовать в одной и той же логике временной шкалы прокрутки, несмотря на то, что находятся в разных частях дерева DOM.
Заключение
Сегодня, в декабре 2024 года, мы рассмотрели большую часть того, что в настоящее время определено вспецификации CSS-анимации при прокрутке на уровне 1. Но я хочу выделить несколько ключевых моментов, которые помогли мне лучше понять эти новые правила, которые вы, возможно, не найдёте в спецификации напрямую:
- Предметы первой необходимости контейнера для прокрутки
Это может показаться очевидным, но для работы анимации с прокруткой необходим контейнер с прокруткой. Проблемы часто возникают при изменении размера таких элементов, как текст или контейнеры, или при тестировании анимации на больших экранах, что приводит к исчезновению области прокрутки. - Воздействие
position: absolute
Использование абсолютного позиционирования иногда может повлиять на ожидаемое поведение анимации при прокрутке. Взаимосвязь между элементами и их родительскими элементами становится сложной, когда применяетсяposition: absolute
- Отслеживание начального состояния элемента
Браузер оценивает состояние элементадоприменения каких-либо преобразований (например,translate
). Это влияет на то, когда начинается анимация, особенно на временных шкалах. Ваша анимация может запуститься раньше или позже ожидаемого времени из-за начального состояния. - Избегайте скрытия переполнения
Использованиеoverflow: hidden
может нарушить механизм поиска прокрутки в анимациях, управляемых прокруткой. Рекомендуемое решение — переключиться наoverflow: clip
. - Производительность
Для достижения наилучших результатов используйте для анимации свойства, оптимизированные для графического процессора, такие как преобразования, непрозрачность и некоторые фильтры. Это позволит избежать сложных вычислений компоновки и перерисовки. С другой стороны, анимация таких элементов, какwidth
,height
, илиbox-shadow
может замедлить работу, поскольку они требуют повторного рендеринга. Вскоре больше свойств, таких какbackground-color
,clip-path
,width
, иheight
можно будет анимировать в компоновщике, что ещё больше повысит производительность. - Используйте
will-change
с умом
Используйте это свойство, чтобы передавать элементы на графический процессор, но применяйте его с осторожностью. Чрезмерное использованиеwill-change
может привести к чрезмерному использованию памяти, поскольку браузер резервирует ресурсы, даже если анимация не меняется часто. - Порядок имеет значение
Если вы используете сокращениеanimation
, всегда ставьтеanimation-timeline
после него. - Прогрессивное усовершенствование и доступность
Объедините медиазапросы для уменьшения количества анимаций с правилом@supports
, чтобы анимация применялась только в том случае, если у пользователя нет ограничений на анимацию и браузер её поддерживает.
Например:
@media screen and (prefers-reduce-motion: no-preference) {
@supports ((animation-timeline: scroll()) and (animation-range: 0% 100%)) {
.my-class {
animation: moveCard linear both;
animation-timeline: view();
}
}
}
Основная сложность, с которой я столкнулся при создании демонстраций, была связана скорее с CSS, чем с анимацией прокрутки. Иногда создать макет и сгенерировать прокрутку было сложнее, чем применить анимацию прокрутки. Кроме того, некоторые вещи, которые поначалу сбивали меня с толку, продолжают меняться, и некоторых из них больше нет (помните, что разработка ведётся уже более пяти лет!):
- оси x и y
Раньше они назывались «горизонтальной» и «вертикальной» осями, и хотя Firefox всё ещё поддерживает старую терминологию, она была обновлена. - Старый
@scroll-timeline
синтаксис
Раньше@scroll-timeline
использовался для объявления временных шкал прокрутки, но в последней версии спецификации это изменилось. - Анимация, управляемая прокруткой, и анимация, связанная со прокруткой
Изначально анимации,управляемыепрокруткой, называлисьсвязаннымис прокруткой. Если вы встретите этот устаревший термин в статьях, проверьте, обновлено ли содержимое в соответствии с последней спецификацией, особенно в отношении таких функций, какtimeline-scope
.