Publicado em
- 5 minutos de leitura
View Transitions API no Angular: Transições Nativas de Rota
A navegação entre telas em Single Page Applications frequentemente sofre com cortes visuais bruscos.
A View Transitions API resolve esse problema no nível do navegador, permitindo transições fluidas entre estados de tela sem bibliotecas pesadas de animação em JavaScript.
No ecossistema Angular, a integração dessa funcionalidade ao Angular Router foi recentemente consolidada e promovida a estável, trazendo um modelo declarativo para enriquecer interfaces.
TL;DR
A integração do Angular Router com a View Transitions API agora é estável no Angular.
Basta adicionar withViewTransitions() ao provideRouter() na configuração da aplicação para ativar animações automáticas de fade entre rotas.
A customização visual acontece inteiramente via CSS global usando as pseudo-classes ::view-transition-old() e ::view-transition-new().
Para regras condicionais de negócio ou acessibilidade, o hook onViewTransitionCreated oferece controle imperativo em TypeScript via contexto de injeção.
O Que É a View Transitions API e Como Ela Opera
A View Transitions API é um padrão web moderno suportado nativamente pelos principais navegadores.
Antes dela, animar a troca de páginas exigia manter elementos saindo e entrando no DOM simultaneamente.
Esse modelo causava vazamentos de memória, duplicava listeners de eventos e quebrava o fluxo natural de renderização.
O navegador opera a transição visual em quatro etapas síncronas bem definidas:
- O navegador congela a renderização e tira um snapshot visual do estado atual da interface.
- O callback de atualização do DOM executa, alterando os nós e componentes na tela.
- O navegador captura o snapshot visual do novo estado renderizado.
- O motor gráfico do navegador executa uma animação de interpolação CSS entre a imagem antiga e a nova.
A API nativa do documento segue esta estrutura básica:
document.startViewTransition(async () => {
await atualizarDOM();
});
Ao encapsular essa mecânica diretamente no Router, o Angular remove a necessidade de chamadas manuais no ciclo de vida dos componentes.
Ativando View Transitions no Angular Router
A ativação no Angular moderno segue a arquitetura de provedores funcionais.
No arquivo de configuração principal da aplicação, adicione o recurso withViewTransitions() aos argumentos de provideRouter.
import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
import { provideRouter, withViewTransitions } from '@angular/router';
import { appRoutes } from './app.routes';
export const appConfig: ApplicationConfig = {
providers: [
provideZoneChangeDetection({ eventCoalescing: true }),
provideRouter(appRoutes, withViewTransitions())
]
};
Quando uma navegação começa, o Angular Router executa o fluxo padrão: guarda de rotas, resolução de dados e carregamento de pacotes via lazy loading.
Assim que a rota de destino está pronta para montagem, o Router aciona document.startViewTransition.
A substituição dos componentes do <router-outlet> acontece no callback da transição.
Em navegadores sem suporte à API, o Router aplica o conceito de progressive enhancement: o DOM é atualizado imediatamente sem animação e sem gerar erros de runtime.
Customizando Animações com CSS e Pseudo-Elementos
Por padrão, o navegador aplica um cross-fade suave de 250 milissegundos sobre a pseudo-raiz ::view-transition.
Para criar comportamentos visuais ricos, como transições morfológicas de cards para páginas de detalhes, você define o atributo CSS view-transition-name.
/* styles.css (estilos globais) */
.product-card-image {
view-transition-name: selected-product-hero;
}
@keyframes slide-to-left {
from {
transform: translateX(0);
opacity: 1;
}
to {
transform: translateX(-100%);
opacity: 0;
}
}
@keyframes slide-from-right {
from {
transform: translateX(100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
::view-transition-old(selected-product-hero) {
animation: 300ms ease-out both slide-to-left;
}
::view-transition-new(selected-product-hero) {
animation: 300ms ease-out both slide-from-right;
}
Dois elementos em rotas diferentes podem compartilhar o mesmo view-transition-name, contanto que nunca coexistam na mesma página renderizada.
O navegador calcula a diferença de posição e escala automaticamente entre o elemento de saída e o de entrada.
Regra mandatória de arquitetura: declare as regras de animação de view transitions sempre em arquivos de estilos globais.
O encapsulamento padrão de componentes no Angular escopa os seletores e impede que o CSS encontre as pseudo-classes da árvore de transição gerada pelo navegador.
Controle Granular com onViewTransitionCreated
Aplicações corporativas necessitam de regras específicas para habilitar ou ignorar transições em cenários particulares.
A função withViewTransitions() aceita um objeto de configuração com a propriedade onViewTransitionCreated.
Esse callback roda dentro de um contexto de injeção de dependência e recebe uma instância de ViewTransitionInfo.
O exemplo abaixo ignora transições quando a navegação altera apenas parâmetros de query string ou âncoras na mesma rota:
import { inject } from '@angular/core';
import {
provideRouter,
withViewTransitions,
Router,
isActive,
IsActiveMatchOptions
} from '@angular/router';
import { appRoutes } from './app.routes';
export const appRouter = provideRouter(
appRoutes,
withViewTransitions({
onViewTransitionCreated: ({ transition }) => {
const router = inject(Router);
const targetUrl = router.currentNavigation()?.finalUrl;
if (!targetUrl) {
return;
}
const matchOptions: Partial<IsActiveMatchOptions> = {
paths: 'exact',
matrixParams: 'exact',
fragment: 'ignored',
queryParams: 'ignored'
};
const isCurrentRouteActive = isActive(targetUrl, router, matchOptions);
if (isCurrentRouteActive()) {
transition.skipTransition();
}
}
})
);
O método transition.skipTransition() cancela a animação visual imediatamente sem interromper a atualização do estado da rota.
Acessibilidade e Respeito a prefers-reduced-motion
Acessibilidade visual é um requisito inegociável na construção de produtos web modernos.
Pessoas com sensibilidade a movimento na tela ou labirintite configuram o sistema operacional para reduzir animações.
O Angular Router não desativa transições automaticamente porque muitos usuários desejam animações discretas em vez de ausência total de transição.
A decisão cabe à aplicação, podendo ser tratada de forma elegante via TypeScript ou CSS.
No callback de transição:
withViewTransitions({
onViewTransitionCreated: ({ transition }) => {
const prefersReducedMotion = window.matchMedia(
'(prefers-reduced-motion: reduce)'
).matches;
if (prefersReducedMotion) {
transition.skipTransition();
}
}
})
Alternativamente, no CSS global:
@media (prefers-reduced-motion: reduce) {
::view-transition-group(*),
::view-transition-old(*),
::view-transition-new(*) {
animation: none !important;
}
}
Essa abordagem garante conformidade com as diretrizes de acessibilidade sem comprometer o design em dispositivos padrão.
Impactos Práticos para Projetos Modernos
Adotar a View Transitions API altera a forma como equipes planejam a experiência de navegação em aplicações Angular.
Primeiro, elimina a dependência de pacotes legados de animação JavaScript que inflavam o bundle inicial e exigiam configurações complexas de triggers de transição.
Segundo, o processamento gráfico ocorre na camada do navegador e na GPU, garantindo taxas estáveis de 60 ou 120 frames por segundo mesmo em dispositivos móveis modestos.
Por fim, o desacoplamento entre a lógica de roteamento em TypeScript e os efeitos visuais em CSS preserva a manutenibilidade do código a longo prazo.
Conclusão
A estabilização da View Transitions API no Angular Router fecha uma lacuna histórica na experiência de navegação de Single Page Applications.
Com apenas uma linha de configuração e estilos CSS nativos, desenvolvedores entregam transições fluidas sem custo de performance em tempo de execução.
Entre na nossa comunidade!
Receba novos posts, novidades do ecossistema Angular e muito mais.
Sobre o autor