Индикатор прогресса прокрутки – это распространенный элемент пользовательского интерфейса, который визуально показывает, какую часть документа или контейнера пользователь уже просмотрел. По мере прокрутки визуальный элемент обновляется, отражая положение пользователя и давая четкое и интуитивно понятное представление о том, сколько контента было просмотрено и сколько осталось.
Рекомендации по внедрению
Чтобы создать индикатор прогресса прокрутки, вам понадобятся две вещи:
- Элемент, который будет использоваться в качестве индикатора выполнения. Обычно это элемент
position: fixedилиposition: absolute, который остается видимым при прокрутке. - Анимация, связанная с положением прокрутки.
Вот что можно сделать:
- Сначала создайте элемент HTML, который будет служить индикатором выполнения. Этот элемент можно оформить по своему вкусу.
- Затем в CSS определите анимацию
@keyframes, которая масштабирует индикатор выполнения. Обычно элемент масштабируется отscaleX(0)доscaleX(1). - Наконец, примените эту анимацию к элементу индикатора выполнения и установите для его свойства
animation-timelineзначение scroll-timeline. Это указывает браузеру управлять ходом анимации на основе положения прокрутки ближайшего предка.
Пример кода
Этот код увеличивает элемент #progress при прокрутке, используя анонимную временную шкалу прокрутки, созданную функцией scroll().
@media (prefers-reduced-motion: no-preference) {
@supports ((animation-timeline: scroll())) {
@keyframes grow-progress {
from { transform: scaleX(0); }
to { transform: scaleX(1); }
}
#progress {
position: fixed;
left: 0; top: 0;
width: 100%; height: 1em;
background: red;
transform-origin: 0 50%;
animation: grow-progress auto linear;
animation-timeline: scroll();
}
}
}
Из-за своего расположения в DOM функция scroll() будет отслеживать ближайший предок-скроллер в направлении block, которым здесь является корневой скроллер.
<body>
<!-- MANDATORY: Purely decorative visual scroll progress bars MUST set aria-hidden="true" to remove the empty element from the assistive technology reading tree -->
<div id="progress" aria-hidden="true"></div>
</body>
Этот код увеличивает элемент #progress при прокрутке с помощью именованной временной шкалы прокрутки, созданной свойством scroll-timeline.
@media (prefers-reduced-motion: no-preference) {
@supports ((animation-timeline: scroll())) {
@keyframes grow-progress {
from { transform: scaleX(0); }
to { transform: scaleX(1); }
}
:root {
scroll-timeline: --tl block;
}
#progress {
position: fixed;
left: 0; top: 0;
width: 100%; height: 1em;
background: red;
transform-origin: 0 50%;
animation: grow-progress auto linear;
animation-timeline: --tl;
}
}
}
Рекомендации
При использовании анимации, управляемой прокруткой, важно следовать нескольким рекомендациям, чтобы обеспечить плавность и доступность:
- РЕКОМЕНДУЕТСЯ включить обнаружение функций. Не все браузеры поддерживают анимацию, управляемую прокруткой. Используйте
@supports (animation-timeline: scroll()), чтобы проверить поддержку и предоставить резервный вариант для браузеров, которые ее не поддерживают.- НЕ ИСПОЛЬЗУЙТЕ пакет
scroll-timeline-polyfillдля резервной стратегии, так как он неполный и имеет много известных проблем. - Если анимация используется только в декоративных целях, выберите прогрессивное улучшение и НЕ добавляйте резервный вариант.
- НЕ ИСПОЛЬЗУЙТЕ пакет
- РЕКОМЕНДУЕТСЯ удалять чисто декоративные элементы из потоков чтения технологий специальных возможностей. Применяйте
aria-hidden="true"к чисто визуальным индикаторам прокрутки, чтобы программы чтения с экрана не сталкивались с пустыми безымянными узлами. - Уважайте предпочтения пользователей. Некоторые пользователи предпочитают, чтобы на веб-страницах было меньше движения. Используйте медиазапрос
prefers-reduced-motion, чтобы отключить или уменьшить анимацию для этих пользователей. - РЕКОМЕНДУЕТСЯ анимировать только эффективные свойства CSS. Чтобы анимация была максимально плавной, анимируйте свойства, которые могут обрабатываться потоком компоновщика браузера, например
transformиopacity. Анимация других свойств, таких какwidthилиheight, может привести к проблемам производительности. - РЕКОМЕНДУЕТСЯ использовать правильный порядок объявления. При использовании сокращенного свойства
animationобъявляйтеanimation-timelineпосле него, чтобы сокращенное свойство не сбрасывало временную шкалу.
При использовании функции scroll() для создания анимации, управляемой прокруткой:
- НЕОБЯЗАТЕЛЬНО. Укажите, какой скроллер вы хотите использовать, если это не ближайший предок. Для этого используйте
scroll(root)илиscroll(self).- Если
root,nearestилиselfнедостаточно, используйте именованную временную шкалу прокрутки.
- Если
- НЕОБЯЗАТЕЛЬНО. Укажите ось, которую нужно отслеживать. Если таргетинг настроен не на ось
blockпо умолчанию (например, при горизонтальной прокрутке), укажите, какую ось нужно отслеживать, с помощьюscroll(block)илиscroll(inline).
При использовании свойства scroll-timeline для создания анимации, управляемой прокруткой:
- РЕКОМЕНДУЕТСЯ использовать для названия CSS-класс
<dashed-ident>. - НЕОБЯЗАТЕЛЬНО. Укажите ось, которую нужно отслеживать. Если таргетинг настроен не на ось
blockпо умолчанию (например, при горизонтальной прокрутке), укажите, какую ось нужно отслеживать с помощьюscroll-timeline-axis. - РЕКОМЕНДУЕТСЯ убедиться, что область поиска работает. Если элемент, объявляющий
scroll-timeline, не является предком анимированного элемента в плоском дереве, сделайте имяscroll-timelineвидимым, используяtimeline-scopeдля общего предка.
Резервные стратегии
Для браузеров, которые не поддерживают анимацию на основе прокрутки, можно использовать резервный вариант, чтобы воссоздать визуальные эффекты. Резервные варианты обычно создаются с помощью прослушивателя прокрутки (для эффектов ScrollTimeline) или IntersectionObserver API (для эффектов ViewTimeline).
В браузерах со встроенной поддержкой анимации на основе прокрутки ВСЕГДА используйте нативную реализацию CSS, так как она более эффективна.
Обратите внимание, что не все эффекты можно воссоздать с помощью резервных объявлений.
В частности, для этого варианта использования следующий скрипт применяет резервный вариант для браузеров, которые не поддерживают анимацию с прокруткой. Он использует прослушиватель прокрутки, чтобы отслеживать положение прокрутки корневого элемента и соответствующим образом обновлять свойство transform индикатора выполнения.
<script>
if (!CSS.supports('animation-timeline', 'scroll()')) {
const progress = document.querySelector('#progress');
window.addEventListener('scroll', () => {
const scrollable = document.documentElement.scrollHeight - window.innerHeight;
const scrolled = window.scrollY;
const progressPercentage = (scrolled / scrollable);
progress.style.transform = `scaleX(${progressPercentage})`;
});
}
</script>