View Transitions API: плавные переходы между страницами без JavaScript

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.

Категория
Поделиться в социальных сетях

Отправить комментарий

0 Комментарии

Отправить комментарий (0)

#buttons=(Хорошо) #days=(20)

Мы используем файлы cookie для улучшения работы сайта. Подробнее
Хорошо
×