scroll() и view(). Поехали.**Основы**
scroll() привязывает анимацию к прогрессу прокрутки контейнера. Элемент просто крутится/двигается/закрашивается в зависимости от того, сколько пикселей мы проскроллили.view() привязывает анимацию к появлению элемента во вьюпорте. Элемент «оживает», когда вползает в кадр, и «умирает», когда выходит. И это идеально для параллакса или плавного появления карточек.Оба механизма работают через
animation-timeline, а за точками старта и конца управляет animation-range.**Прогресс-бар без единой строчки JS**
Классика: полоска сверху показывает, сколько прочитано. Раньше — слушатель скролла и
requestAnimationFrame. Теперь — 5 строк CSS:.progress {
position: fixed;
top: 0; left: 0;
width: 100%; height: 4px;
background: #ff4d00;
transform-origin: left;
animation: scale linear;
animation-timeline: scroll();
}
@keyframes scale {
from { transform: scaleX(0); }
to { transform: scaleX(1); }
}Всё.
scroll() без аргументов = отслеживаем скролл ближайшего предка (или корня, если предка-скроллера нет). Анимация идёт ровно от верха страницы до низа.**Параллакс через
view()**Берём картинку, которая должна двигаться с другой скоростью, пока она на экране. Вместо scroll-слушателя и пересчёта позиций:
.parallax-image {
animation: drift linear;
animation-timeline: view();
animation-range: entry 0% cover 40%;
}
@keyframes drift {
from { transform: translateY(15%); }
to { transform: translateY(-15%); }
}Поясню значения
entry, cover, exit. Палитра простая:-
entry — элемент выезжает снизу/сверху в кадр-
cover — полностью на экране-
exit — покидает вьюпортentry 0% cover 40% значит: анимация начинается в момент появления и заканчивается, когда элемент прошёл 40% высоты экрана. За счёт этого картинка «сдвигается» независимо от скорости скролла.**Важный нюанс:
animation-range**Если у вас контейнер высотой 200%, а анимация должна идти только на середине скролла — играйтесь именно через range.
scroll(root) + range: 0% 50% даст эффект, заканчивающийся на половине страницы. Это заменяет кучу логики «если y > X».**Бонус-фича:
animation-timeline: view(block)**По умолчанию отслеживается ось блока (вертикаль) или инлайна (горизонталь). Можно явно указать
view(inline) для горизонтальных слайдеров-каруселей с прокруткой по X. Тоже без JS.**Что под капотом и поддержка**
Работает только с ключевыми кадрами — CSS-переходы так не умеют.
animation-timeline можно комбинировать с обычной animation-duration, но при наличии timeline длительность игнорируется: прогрессом правит скролл.Поддержка в 2025-м: Chrome 115+, Edge 115+, Safari 26+ (с префиксом
-webkit- в iOS 26). Firefox — за флагом, но уже в активной разработке. Для отстающих браузеров это деградирует безболезненно: без поддержки просто не будет анимации.**Моя рекомендация**
Не пишите свой параллакс через JS, если это обычный маркетинговый лендинг. Нативный scroll-driven API считается на стороне compositor, поэтому дёрганий и микролагов на слабых устройствах меньше, чем при ручном обновлении свойств из JS.
Вывод: добавьте
scroll() на прогресс-бар, view() на карточки — почувствуете разницу в скорости вёрстки сразу.