Durante anos, animações de transição entre páginas foram território exclusivo de frameworks como React com Framer Motion, ou bibliotecas pesadas de animação. O browser simplesmente não tinha primitivas para isso.
A View Transitions API muda isso.
Com ela, você consegue animar a troca de conteúdo na tela — seja numa SPA mudando de rota, seja num site tradicional navegando entre páginas — usando apenas CSS e uma única chamada nativa.
O problema que ela resolve
Imagine que o usuário clica em um card de produto e a imagem do card "voa" até ocupar toda a tela na página de detalhe. Isso parecia impossível sem JavaScript complexo que rastreasse posições DOM, clonasse elementos e sincronizasse animações.
A View Transitions API faz exatamente isso, mas deixa o browser cuidar da parte difícil.
Como funciona
O mecanismo é simples:
- Você chama
document.startViewTransition(callback) - O browser tira um snapshot do estado atual da tela
- Executa o
callback(que atualiza o DOM) - Tira um snapshot do novo estado
- Anima entre os dois snapshots com uma cross-fade padrão — ou com o CSS que você definir
document.startViewTransition(() => {
// qualquer mudança de DOM vai aqui
updateContent();
});
Só isso já dá uma animação suave de fade entre o estado antigo e o novo. Sem biblioteca, sem dependência.
Transições de elementos específicos
A parte mais poderosa é nomear elementos para que o browser os anime individualmente:
/* O card na lista */
.product-card img {
view-transition-name: product-image;
}
/* A imagem na página de detalhe */
.product-detail img {
view-transition-name: product-image;
}
Com o mesmo view-transition-name nos dois elementos, o browser entende que são "o mesmo objeto" e cria uma animação suave de posição e tamanho entre eles. É o chamado shared element transition.
Customizando com CSS
As pseudo-classes ::view-transition-old e ::view-transition-new expõem os snapshots para estilização:
@keyframes slide-in {
from { transform: translateX(100%); opacity: 0; }
to { transform: translateX(0); opacity: 1; }
}
@keyframes slide-out {
from { transform: translateX(0); opacity: 1; }
to { transform: translateX(-100%); opacity: 0; }
}
::view-transition-old(root) {
animation: slide-out 300ms ease-out;
}
::view-transition-new(root) {
animation: slide-in 300ms ease-out;
}
Navegação entre páginas (MPA)
A API também funciona em Multi-Page Apps (navegação tradicional com <a href>), com opt-in via meta tag:
<meta name="view-transition" content="same-origin">
Com isso, qualquer navegação entre páginas do mesmo domínio recebe a animação configurada. Sem JavaScript, sem roteador, sem framework.
Nota: para MPAs, o suporte exige Chrome 126+. Como progressive enhancement — o site funciona normalmente onde não há suporte — o risco é zero.
prefers-reduced-motion é obrigatório
Usuários com sensibilidade a movimento podem desativar animações no sistema operacional. Sempre respeite:
@media (prefers-reduced-motion: reduce) {
::view-transition-group(*),
::view-transition-old(*),
::view-transition-new(*) {
animation: none !important;
}
}
Quando faz sentido usar
| Cenário | Vale a pena? |
|---|---|
| SPA com rotas (Next.js, React Router) | Sim — substitui Framer Motion em muitos casos |
| Blog ou site de conteúdo | Sim — MPA transition com um meta tag |
| Dashboard com muito estado | Com cuidado — teste com dados reais |
| Animação complexa com física | Não — use uma lib especializada |
Suporte atual
- Chrome/Edge 111+: suporte completo para SPAs
- Chrome 126+: suporte para MPAs
- Firefox / Safari: em desenvolvimento
Para produção, use como progressive enhancement: a experiência base funciona sem animação, a API é um upgrade silencioso para quem tem suporte.
A View Transitions API é um daqueles casos raros onde o browser entregou uma primitiva que resolve um problema real sem adicionar complexidade. Antes de instalar uma biblioteca de animação, verifique se ela já resolve o seu caso.