Assinar
Voltar
Frontend

View Transitions API: transições suaves entre páginas sem SPA

A API de transições de visualização amadureceu e chegou aos navegadores baseados em Chromium e ao Safari. Entenda como animar a navegação entre páginas com CSS, sem depender de um framework single-page.

λ

Durante anos, quem quis transições suaves entre páginas foi praticamente obrigado a construir uma single-page application (SPA). O motivo era simples: no modelo tradicional de múltiplas páginas (MPA), cada clique em um link descarta o documento atual e pinta o próximo do zero, com aquele “flash” seco entre telas. A View Transitions API mudou esse cenário e permite animar a transição entre estados da interface — e até entre documentos diferentes — usando principalmente CSS.

Dois modos: mesmo documento e entre documentos

A API funciona de duas formas. No modo same-document, típico de SPAs, você envolve a atualização do DOM em document.startViewTransition(). O navegador tira um “retrato” do estado antigo, executa a função que altera o DOM e anima do estado antigo para o novo automaticamente.

if (!document.startViewTransition) {
  atualizarView(); // fallback para navegadores sem suporte
  return;
}
document.startViewTransition(() => atualizarView());

O retorno é um objeto ViewTransition com promessas úteis: updateCallbackDone, ready (pseudo-elementos criados, animação prestes a começar) e finished (animação concluída).

O modo cross-document é o que mais empolga, porque atende sites MPA clássicos — WordPress, e-commerce, blogs, documentação. Aqui não é preciso JavaScript: basta que a página de origem e a de destino declarem, no CSS, a regra de adesão.

@view-transition {
  navigation: auto;
}

As transições entre documentos entregam o polimento de uma SPA sem o custo de JavaScript de uma SPA.

Como o navegador monta a animação

Quando a transição dispara, o navegador cria uma árvore de pseudo-elementos sobreposta à página. No topo fica ::view-transition, e para cada trecho animado existe um grupo com dois retratos: ::view-transition-old() (imagem estática do estado antigo, que sai) e ::view-transition-new() (o novo conteúdo, ao vivo, que entra). O comportamento padrão é um cross-fade suave entre os dois.

Para animar elementos de forma independente, você atribui a eles um view-transition-name único. Assim o navegador entende que aquele elemento “é o mesmo” nas duas telas e faz o morph de posição e tamanho entre elas.

.hero {
  view-transition-name: capa-do-artigo;
}

::view-transition-old(capa-do-artigo) {
  animation: 0.25s linear both encolher;
}
::view-transition-new(capa-do-artigo) {
  animation: 0.25s linear both crescer;
}

Atenção a uma regra prática: cada view-transition-name precisa ser único entre os elementos renderizados. Nomes repetidos quebram a transição.

Controle fino com eventos e tipos

No modo entre documentos, dois eventos dão controle sobre o processo: pageswap, disparado na página que sai antes do último quadro, e pagereveal, na página que entra antes do primeiro render. Ambos expõem o objeto viewTransition, útil para, por exemplo, ler a URL de destino e decidir a direção da animação.

Também é possível declarar tipos de transição para variar o efeito conforme a navegação (avançar, voltar):

  • @view-transition { navigation: auto; types: slide, forwards; } no CSS;
  • ou dinamicamente, com e.viewTransition.types.add('forwards') dentro de pagereveal;
  • e então estilizar com o seletor :active-view-transition-type(forwards).

Requisitos, limites e acessibilidade

Alguns pontos merecem cautela. As transições entre documentos exigem que origem e destino estejam na mesma origem (mesmo esquema, host e porta) e que ambas tenham a regra @view-transition. Elas cobrem navegações por link e por histórico (voltar/avançar), mas não são acionadas por digitação na barra de endereço, favoritos ou recarregamento. Há ainda um timeout de segurança de 4 segundos.

Do ponto de vista de experiência, respeite quem prefere menos movimento. É simples desativar a animação quando o usuário sinaliza essa preferência no sistema:

@media (prefers-reduced-motion: reduce) {
  ::view-transition-old(root),
  ::view-transition-new(root) {
    animation: none;
  }
}

Vale a pena adotar agora?

O suporte já é bom. O modo same-document funciona em navegadores Chromium e no Safari há algumas versões. O modo cross-document chegou ao Chrome e Edge 126+ e ao Safari 18.2+; o Firefox ainda não o suporta no momento desta publicação. Como toda a mecânica é uma camada de progressive enhancement, isso raramente é um problema: onde não há suporte, a navegação simplesmente acontece sem animação, sem quebrar nada.

Na prática, a View Transitions API é uma das adições mais impactantes da plataforma web recente. Ela devolve aos sites MPA um recurso de polimento que parecia exclusivo de SPAs pesadas, com pouquíssimo código e sem sacrificar performance. Se o seu projeto é um site de conteúdo tradicional, adicionar @view-transition no CSS já é um ótimo primeiro passo.

Fontes

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *