CSS-правило @view-transition { navigation: auto; } включает плавный переход между двумя страницами сайта при обычном клике по ссылке - без единой строчки JavaScript. Правило нужно добавить в стили ОБЕИХ страниц перехода: без него на одной из них браузер просто перелистнёт страницы как обычно, без анимации и без ошибки.
В этом уроке
Попробуй прямо сейчас: этот блокнот показывает синтаксис - можно менять view-transition-name, длительность анимации, оформление карточки. Но сам переход физически нельзя показать в одном окне предпросмотра: он появляется только при переходе между двумя РЕАЛЬНЫМИ HTML-страницами через настоящую браузерную навигацию (клик по ссылке), а здесь всегда одна и та же страница - редактируй код и смотри, как он читается, но анимации ты здесь не увидишь. Поэтому ниже - настоящая запись такого перехода между двумя страницами, снятая в браузере.
Настоящая запись перехода между двумя HTML-страницами (Chrome, @view-transition + view-transition-name) - маленькая карточка со страницы списка плавно "перетекает" в крупную карточку на странице товара, а не исчезает и появляется заново.
Как включить переход между страницами: @view-transition
Синтаксис минимальный: @view-transition {
navigation: auto;
} в стилях страницы включает переходы для пользовательских навигаций (клик по ссылке, кнопки вперёд/назад браузера). Значение navigation: none выключает переходы и стоит по умолчанию, если правило вообще не добавлено. Работает это только между страницами одного происхождения (тот же протокол, домен и порт) - переход на другой домен или поддомен анимации не получит, браузер просто перелистнёт страницы как обычно.
/* только на странице списка */
@view-transition { navigation: auto; } - на странице товара правила нет, переход не сработает.
/* на ОБЕИХ страницах: и списка, и товара */
@view-transition { navigation: auto; } - только так переход действительно запустится.
Собственная проверка (Playwright, реальная навигация между двумя HTML-файлами по клику на ссылку, не эмуляция): с правилом на обеих страницах браузер после перехода запускает 10 одновременных CSS-анимаций - подтверждено через реальный список document.getAnimations() сразу после навигации. Без правила вообще - ровно 0 анимаций, переход происходит мгновенно. А если правило есть только на стартовой странице, а на целевой его нет - тоже 0 анимаций: наличия на одной странице недостаточно, нужно на обеих одновременно.
Без своих правил переход по умолчанию выглядит как плавное взаимное выцветание: старая страница гаснет, новая проявляется поверх неё. Поддержка на сентябрь 2026: Chrome и Edge 126+ (стабильно с 11 июня 2024 года), Safari 18.2+. Firefox пока не поддерживает - без обещанных сроков. Деградация плавная: в неподдерживающем браузере переход просто происходит как обычная навигация без анимации, без единой ошибки в консоли - это прогрессивное улучшение, а не риск что-то сломать.
Своя анимация и общий элемент между страницами: view-transition-name
Браузер строит переход через пару псевдоэлементов: ::view-transition-old(root) - статичный снимок старой страницы, анимируется на выход, и ::view-transition-new(root) - живой рендер новой страницы, анимируется на вход. Дефолтное выцветание переопределяется обычными @keyframes и animation - тем же синтаксисом, что уже разбирался в уроке про правило @keyframes.
@keyframes slide-out-left {
to { transform: translateX(-100%); }
}
@keyframes slide-in-right {
from { transform: translateX(100%); }
}
html::view-transition-old(root) { animation: slide-out-left 0.3s; }
html::view-transition-new(root) { animation: slide-in-right 0.3s; } - вместо выцветания страницы "уезжают" в сторону.
Собственная проверка (тот же метод - реальная навигация, не эмуляция): после замены дефолтных псевдоэлементов на свои @keyframes браузер после перехода реально запускает именно slide-out-left и slide-in-right вместо стандартных анимаций выцветания - подтверждено точными именами анимаций из document.getAnimations(), а не просто написано в документации.
Чтобы КОНКРЕТНЫЙ элемент (например картинка или карточка товара) плавно "перетёк" с одной страницы на другую, а не просто исчез и появился отдельно, ему на обеих страницах нужно одно и то же значение view-transition-name: .hero { view-transition-name: product-hero; }. Для одиночного статичного элемента (заголовок, логотип, одна карточка - не элемент из повторяющегося списка) этого достаточно, JavaScript не нужен: значение должно совпадать в стилях обеих страниц, и браузер сам построит непрерывную анимацию размера и позиции между двумя состояниями элемента - именно так снята запись выше. Единственное жёсткое ограничение: значение должно быть уникальным в пределах документа в момент перехода - если у двух элементов на одной странице одновременно окажется одно и то же имя, браузer не выберет "более подходящий", а полностью отменит переход целиком.
И ещё один нюанс, который легко упустить: prefers-reduced-motion браузер сам не обрабатывает - переходы играют с обычной скоростью даже при включённой в ОС настройке "меньше анимаций", если явно не добавить уже знакомый по прошлому уроку @media (prefers-reduced-motion: reduce) - только теперь для псевдоэлементов ::view-transition-*.
Частые ошибки новичков
| Ошибка | Что происходит | Как исправить |
|---|---|---|
| Добавить @view-transition только на одной из двух страниц перехода | Переход не срабатывает вообще - навигация происходит как обычно, без анимации и без ошибки в консоли | Добавлять правило в стили ОБЕИХ страниц, между которыми должен быть переход |
| Ждать эффекта при переходе на другой домен или поддомен | Работает только same-origin (тот же протокол, домен и порт) - переход на другой сайт или поддомен анимации не получит | Использовать для навигации в пределах одного и того же origin |
| Одинаковый view-transition-name у двух элементов на одной странице одновременно | Браузер не может решить, какой из них должен "перетечь" - переход целиком отменяется, а не просто ломается визуально | Держать значения view-transition-name уникальными в пределах документа в момент перехода |
| Считать, что prefers-reduced-motion автоматически смягчает переходы между страницами | Браузер не отключает и не смягчает переходы сам - анимация играет с обычной скоростью даже при включённой настройке | Добавлять свой @media (prefers-reduced-motion: reduce) для псевдоэлементов ::view-transition-* |
Шпаргалка
| Запись | Что означает |
|---|---|
| @view-transition { navigation: auto; } | Включает переходы между страницами - нужно на ОБЕИХ страницах |
| ::view-transition-old(root) / ::view-transition-new(root) | Старая и новая страница целиком - по умолчанию плавно выцветают друг в друга |
| view-transition-name: имя | "Склеивает" один и тот же элемент на двух страницах - он плавно перетекает, а не исчезает и появляется |
| Same-origin only | Работает только между страницами одного сайта (протокол + домен + порт) |
| Chrome/Edge 126+, Safari 18.2+ | Firefox пока не поддерживает - без поддержки переход просто происходит как обычно |
Коротко: отвечаем на вопросы
Нужен ли JavaScript, чтобы использовать View Transitions API между страницами сайта?
Нет - для перехода между двумя отдельными HTML-страницами (обычный многостраничный сайт вроде этого) достаточно одного CSS-правила @view-transition { navigation: auto; } на обеих страницах, JavaScript не требуется вообще. У API есть и другая, JS-версия - document.startViewTransition() - но она предназначена для одностраничных приложений (SPA), где переходы происходят внутри одного документа без перезагрузки, и в этот курс не входит.
Сработает ли переход, если правило @view-transition стоит только на одной из двух страниц?
Нет. Собственная проверка через реальную навигацию между двумя HTML-файлами подтвердила: если правило есть только на стартовой странице, а на целевой его нет (или наоборот) - браузер запускает ровно 0 анимаций, переход происходит как обычно, без ошибки в консоли. Правило обязательно на обеих страницах перехода одновременно.
Как сделать так, чтобы конкретный элемент плавно "перетёк" с одной страницы на другую, а не просто исчез и появился?
Задать этому элементу одинаковое значение view-transition-name в стилях обеих страниц, например view-transition-name: product-hero. Для одиночного статичного элемента (не для элемента из повторяющегося списка) этого достаточно на чистом CSS, без JavaScript - браузер сам построит непрерывную анимацию размера и позиции между двумя состояниями элемента. Значение должно быть уникальным в пределах каждой страницы в момент перехода.
Cross-document переходы (та форма API, что разобрана в этом уроке) стабильно заработали в Chrome и Edge 126 - релиз вышел 11 июня 2024 года. До этого релиза для похожего эффекта между страницами приходилось полностью переписывать сайт в SPA и подключать JS-версию того же API. Документация Chrome for Developers: Cross-document view transitions.