View Transitions API: полный обзор
Как работает View Transitions API: переходы между страницами одним правилом CSS, общие элементы, переходы внутри страницы, поддержка браузерами, три проверенных примера, ошибки и правила.
Коротко
View Transitions API — возможность браузера анимировать смену одного состояния страницы другим или переход с одной страницы на следующую. Браузер делает снимок старого состояния, отрисовывает новое и проигрывает между ними плавный переход: по умолчанию растворение, а парой строк CSS — фото, которое перелетает из каталога на страницу товара, неподвижная шапка и сдвигающееся содержимое. Для многостраничного сайта это одно правило CSS без JavaScript, внутри одной страницы — один вызов функции. Где браузер не поддерживает переходы, сайт просто работает без анимации.
View Transitions коротко
Главные факты одной таблицей: что делает API, два его вида и что бывает без поддержки.
- Что это
- API браузера для анимированной смены состояний и страниц
- Два вида
- Внутри страницы —
startViewTransition(); между страницами — правило CSS@view-transition - Как работает
- Снимок старого состояния, новое состояние и анимация между ними в псевдоэлементах
- По умолчанию
- Растворение всей страницы
- Общие элементы
- Одинаковый
view-transition-nameс обеих сторон — элемент переезжает с места на место - Без поддержки
- Обычная смена без анимации — ничего не ломается
- Стандарт
- CSS View Transitions Module, уровни 1 и 2, W3C
Возможности и поддержка браузерами
Восемь частей API с назначением и поддержкой. У самых новых поддержку проверяют перед применением — без неё они просто игнорируются.
| Возможность | Для чего | Поддержка |
|---|---|---|
| startViewTransition() | переход внутри одной страницы | все современные |
| view-transition-name | элемент, который переезжает отдельно | все современные |
| ::view-transition-old/new | своя анимация старого и нового состояния | все современные |
| @view-transition | переходы между страницами сайта | Chrome, Edge, Safari |
| pageswap, pagereveal | события для настройки перехода между страницами | Chrome, Edge, Safari |
| view-transition-class | одна анимация на группу элементов | новое — проверять |
| типы переходов | разные анимации вперёд и назад | новое — проверять |
| match-element | автоматические имена для множества элементов | новое — проверять |
Где переходы помогают: 8 случаев
Переход стоит добавлять там, где он объясняет, что произошло: куда делся элемент и откуда появился.
| Случай | Вид | Что движется |
|---|---|---|
| Каталог → товар | между страницами | фото вырастает в большое |
| Список статей → статья | между страницами | обложка и заголовок |
| Любая страница сайта | между страницами | содержимое; шапка стоит |
| Фильтр каталога | внутри страницы | карточки на новые места |
| Вкладки | внутри страницы | подчёркивание и содержимое |
| Шаги формы | внутри страницы | шаг уезжает, следующий приезжает |
| Светлая и тёмная тема | внутри страницы | новая тема раскрывается от кнопки |
| Экраны Telegram Mini App | внутри страницы | экран как в нативном приложении |
Плюсы и минусы View Transitions
Сложную часть анимации браузер делает сам. И выгоды, и ограничения идут отсюда.
Плюсы · 5
-
Одна строка на весь сайт
@view-transitionпревращает каждый клик между страницами в плавную смену. -
Без библиотеки
Ни килобайта JavaScript ради переходов между страницами.
-
Ощущение приложения без SPA
Сайт остаётся обычными страницами — простыми для поисковиков и быстрыми в загрузке.
-
Безопасно добавлять
Без поддержки сайт просто работает без анимации.
-
Анимации на CSS
Вид перехода задаётся обычными ключевыми кадрами и псевдоэлементами.
Минусы · 4
-
Неровная поддержка между страницами
Переходы между страницами пока работают не во всех браузерах.
-
Снимки — это картинки
При смене размеров текст в снимке растягивается, и это нужно настраивать.
-
Страница пока не кликается
Пока идёт переход, клики уходят в его слой — длинные анимации мешают.
-
Только в пределах сайта
Переходы между страницами работают только в пределах одного домена.
Как выглядят View Transitions: 3 примера
Переход между страницами, общее фото и фильтр внутри страницы. Все три запущены в браузере на локальном сервере.
Переходы между страницами
Одно правило включает переходы, два псевдоэлемента задают их вид, а ветка для отказа от движения убирает их полностью.
/* Этот файл подключают обе страницы: клик по ссылке становится плавным переходом */
@view-transition {
navigation: auto;
}
/* Вся страница: старая гаснет, новая слегка поднимается */
::view-transition-old(root) {
animation: 0.2s ease-in both fade-out;
}
::view-transition-new(root) {
animation: 0.3s ease-out both rise-in;
}
@keyframes fade-out {
to { opacity: 0; }
}
@keyframes rise-in {
from { opacity: 0; translate: 0 1rem; }
}
/* Кто отключил движение в системе, получает мгновенную смену */
@media (prefers-reduced-motion: reduce) {
::view-transition-group(*),
::view-transition-old(*),
::view-transition-new(*) {
animation: none !important;
}
}
Общее фото
Одно и то же имя на двух страницах — и миниатюра перелетает в фото товара.
<!-- Каталог: у каждой миниатюры своё имя -->
<a href="/catalog/oak-table">
<img src="/img/oak-table.webp" alt="Дубовый стол" width="320" height="240"
style="view-transition-name: product-a100">
</a>
<!-- Страница товара: у фото то же имя —
браузер переносит миниатюру в большое фото -->
<img src="/img/oak-table.webp" alt="Дубовый стол" width="960" height="720"
style="view-transition-name: product-a100">
Фильтр внутри страницы
Карточки переезжают на новые места; в браузере без поддержки фильтр срабатывает мгновенно.
// Каждая карточка один раз получает своё имя — браузер следит за каждой отдельно
document.querySelectorAll('.card').forEach((card, i) => {
card.style.viewTransitionName = `card-${i}`;
});
// Фильтр каталога без перезагрузки: карточки плавно переезжают на новые места
function applyFilter(category) {
const update = () => {
for (const card of document.querySelectorAll('.card')) {
card.hidden = category !== 'all' && card.dataset.category !== category;
}
};
// Нет поддержки — фильтр просто работает без анимации
if (!document.startViewTransition) {
update();
return;
}
document.startViewTransition(update);
}
Частые ошибки с View Transitions
-
Два элемента с одним именем
Если имя повторяется на странице, браузер пропускает весь переход.
-
Медленные анимации
Переход дольше полсекунды делает медленным каждый клик.
-
Нет ветки для отказа от движения
Те, кто отключил движение в системе, всё равно его получают.
-
Анимировать всё подряд
Десятки движущихся элементов превращают переход в шум; хватает одного-двух.
-
Ждать, что он спрячет медленный сервер
Переход начинается, только когда новая страница готова, — медленная страница остаётся медленной.
-
Растянутый снимок
Элемент, меняющий пропорции, искажается; это правят в
::view-transition-oldи-new.
6 правил переходов в рабочем проекте
-
01
Начать с одной строки
@view-transition { navigation: auto; }сразу даёт всему сайту мягкую смену страниц. -
02
Имя для шапки
Шапка со своим именем стоит на месте, пока меняется содержимое.
-
03
Только ключевые элементы
Фото, заголовок, обложка — то, за чем следит глаз.
-
04
Уникальные имена из данных
Имя строится из id товара или статьи — оно совпадает на обеих страницах.
-
05
От 0,2 до 0,4 секунды
Достаточно, чтобы заметить, и мало, чтобы ждать.
-
06
Проверить, потом вызвать
Внутри страницы — всегда ветка для браузеров без
startViewTransition.
Вопросы о View Transitions
Что такое View Transitions API?
Возможность браузера анимировать смену состояний страницы или переход между страницами.
Нужен ли JavaScript?
Между страницами — нет, хватает одного правила CSS; внутри страницы — один вызов функции.
Какие браузеры поддерживают?
Переходы внутри страницы — все современные; между страницами — Chrome, Edge и Safari, остальные догоняют.
Что видят остальные браузеры?
Обычную смену страницы без анимации — ничего не ломается.
Может ли он заменить одностраничное приложение?
Для многих сайтов да: плавные переходы были главной причиной делать SPA, а теперь они есть у обычных страниц.
Влияет ли на SEO?
Нет: страницы остаются обычным HTML, а переход — это несколько строк CSS.
Поддерживают ли его фреймворки?
Да, многие роутеры вызывают его сами — например, в Astro это встроено.
Форма
Переходы
для сайта
Делаю переходы между страницами на CSS и View Transitions API — без тяжёлых библиотек и без превращения сайта в одностраничное приложение. Расскажите о проекте — отвечу в течение рабочего дня.