As transições de visualização entre documentos permitem criar transições suaves, semelhantes às de apps, entre diferentes páginas de um aplicativo de várias páginas (MPA, na sigla em inglês). Por padrão, o navegador realiza um cross-fade, mas é possível personalizar isso para combinar com a estética do seu site.
Etapas de implementação
1. Ativar as transições de visualização entre documentos
As páginas de origem e de destino precisam ativar as transições de visualização para que o navegador as acione na navegação.
/* Respect user's preference for reduced motion */
@media (prefers-reduced-motion: no-preference) {
/* Add to a global stylesheet shared by both pages */
@view-transition {
/* Enables transitions for same-origin navigations */
navigation: auto;
}
}
2. Personalizar animações de transição (opcional)
É possível segmentar os estados antigo e novo da transição usando pseudoelementos para criar efeitos como slides ou revelações.
/* Customizing the outgoing page animation */
::view-transition-old(root) {
/* Move the old page out to the left */
animation: 0.4s ease-in both slide-out;
}
/* Customizing the incoming page animation */
::view-transition-new(root) {
/* Move the new page in from the right */
animation: 0.4s ease-out both slide-in;
}
@keyframes slide-out {
to { transform: translateX(-20%); opacity: 0; }
}
@keyframes slide-in {
from { transform: translateX(100%); }
}
3. Criar transições direcionais (opcional)
Talvez você queira efeitos de transição diferentes dependendo das páginas que está navegando. Por exemplo, ao navegar de uma página inicial para uma página de contato, talvez você queira que o novo conteúdo apareça vindo da direita. Ao voltar para a página inicial, não faria sentido ter o mesmo efeito.
Se a página para onde você está navegando sempre tiver o mesmo tipo de transição, independentemente de como você chegar até ela, especifique-a com types na regra @view-transition.
@media (prefers-reduced-motion: no-preference) {
@view-transition {
navigation: auto;
/* Specify the types of view transitions that will always be used on this page. */
types: previous;
}
}
Também é possível especificar condicionalmente tipos de transição dentro de um listener de eventos para pagereveal.
window.addEventListener("pagereveal", async (e) => {
if (e.viewTransition && window.navigation?.activation) {
// Use application-specific logic to compute a transition type
const transitionType = yourTransitionTypeLogic(navigation.activation.from, navigation.activation.entry);
e.viewTransition.types.add(transitionType);
}
});
Em seguida, use o pseudosseletor :active-view-transition-type() para aplicar as diferentes animações para cada tipo.
:active-view-transition-type(next) {
&::view-transition-old(root) {
animation-name: slide-out-next;
}
&::view-transition-new(root) {
animation-name: slide-in-next;
}
}
:active-view-transition-type(previous) {
&::view-transition-old(root) {
animation-name: slide-out-previous;
}
&::view-transition-new(root) {
animation-name: slide-in-previous;
}
}
Estratégias de fallback
Se um navegador não for compatível com transições de visualização ou transições de visualização entre documentos, ele vai realizar uma navegação padrão instantânea na página. As transições de visualização entre documentos são um aprimoramento progressivo. A funcionalidade principal do site não é afetada.
Para verificar a compatibilidade em JavaScript:
if ('onpagereveal' in window) {
// Browser supports cross-document view transitions
}
Se um navegador não for compatível com a API Navigation, não será possível usá-la para determinar um tipo de transição. Use um método alternativo para determinar o tipo de transição ou forneça um tipo de transição substituto. Caso contrário, o navegador vai realizar uma navegação padrão instantânea na página.
Para verificar a compatibilidade em JavaScript:
if (window.navigation?.activation) {
// Browser supports the Navigation API
}