Publicado em

- 5 minutos de leitura

View Transitions API no Angular: Transições Nativas de Rota

img of 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:

  1. O navegador congela a renderização e tira um snapshot visual do estado atual da interface.
  2. O callback de atualização do DOM executa, alterando os nós e componentes na tela.
  3. O navegador captura o snapshot visual do novo estado renderizado.
  4. 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.

Imagem com o texto: Curso Dominando Agentes de IA como um robô a frente da logo do Angular. Logo abaixo existe um botão com o texto "Eu quero!"

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

Author's photo
Henrique Custódia Arquiteto Frontend, entusiasta Angular, cat lover, criador de conteúdo e fundador da Code Dimension!