Conteúdo deste artigo
- A configuração
- Dissolver pixelização
- Limpe
- Girar para dentro e para fora
- Eliminação do círculo
- Empurrão diagonal
- Cortina revelada
- Inversão 3D
- Alguma receita legal que você queira compartilhar?
As transições de visualização são muito, muito legais. Não só isso, mas eles estão começando a aparecer em todos os lugares . Tenho certeza de que você é como eu e encontrou mais de alguns na natureza que fazem você pensar uau e deseja usá-los instantaneamente em seu próprio site ou projeto.
Ao mesmo tempo, as transições de visualização podem ser difíceis de “obter” no início. Eles podem ser simples , claro, mas quase tudo além de um cross-fade envolve várias partes móveis.
Costumo achar que a melhor maneira de aprender algo novo é ver o código, usá-lo eu mesmo e depois desenvolvê-lo. Então, coletei sete receitas de transição de visualização exatamente para isso. Analisaremos a configuração básica, demonstraremos as receitas e deixaremos você à vontade para experimentar!
Não há problema em ir abaixo e apenas copiar aquela que você mais gosta, mas se quiser entender o que são as transições de visualização, recomendo que você leia primeiro uma introdução rápida antes de passar para as receitas.
Ah, e antes de começarmos, é importante notar que as transições de visualização são de fato básicas e suportadas por todos os principais navegadores enquanto escrevo isto. Mas alguns tipos de animações podem ou não ser suportados por um navegador específico, então fique de olho e teste, como sempre.
A configuração
Para cada transição de visualização, precisaremos fazer uma pequena configuração antecipadamente. Primeiro, precisamos ativar para eles usando o @view-transition at-rule em ambos páginas — a página em que estamos e a página para a qual estamos fazendo a transição. Se você estiver usando modelos em seu site, isso pode estar no modelo de cabeçalho para que seja aplicado globalmente em todos os lugares.
@media (prefers-reduced-motion: no-preference) {
@view-transition {
navigation: auto;
types: <transition-type>;
}
}
Esse @media (prefers-reduced-motion: no-preference) { é a única parte que você não pode copiar e colar diretamente. É um espaço reservado para o descritor
@view-transition {
navigation: auto;
types: <transition-type>;
}
}<transition-type> , algo que abordamos em detalhes antes . É mais sutil do que isso, mas <transition-type> são basicamente o nome da animação que damos a uma transição específica. Dessa forma, se estivermos trabalhando com múltiplas transições, podemos ser explícitos sobre quais delas estão ativas para evitar que entrem em conflito umas com as outras. Mas leia o artigo vinculado para se aprofundar nele.
Observe como temos o @view-transition protegido atrás da consulta de mídia @view-transition. Nem todo mundo deseja movimento em suas páginas e essa é uma preferência que pode ser definida no nível do sistema operacional, portanto, respeitaremos isso quando necessário desta forma.
Por último, aplicaremos nossa animação da seguinte forma:
html:active-view-transition-type(<transition-type>)::view-transition-old(root) {
animation: a-cool-outgoing-animation 1.4s ease forwards;
}
html:active-view-transition-type(<transition-type>)::view-transition-new(root) {
animation: a-cool-incoming-animation 1.4s ease forwards;
}
…onde o prefers-reduced-motion: no-preference pseudo corresponde à transição html:active-view-transition-type(<transition-type>)::view-transition-old(root) {
animation: a-cool-outgoing-animation 1.4s ease forwards;
}
html:active-view-transition-type(<transition-type>)::view-transition-new(root) {
animation: a-cool-incoming-animation 1.4s ease forwards;
} que definimos no @view-transition regra. Por exemplo, se estivermos chamando uma animação que chamamos de type, então usaríamos isso na regra assim:
@media (prefers-reduced-motion: no-preference) {
@view-transition {
navigation: auto;
types: <transition-type>;
}
}
…bem como o pseudo como este:
/* The "current" page */
html:active-view-transition-type(bounce)::view-transition-old(root) {
animation: bounce-in 1.4s ease forwards;
}
/* The page we're transitioning to */
html:active-view-transition-type(bounce)::view-transition-new(root) {
animation: bounce-in 1.4s ease forwards;
}
OK, isso é contexto suficiente para começar com as receitas. Novamente, sinta-se à vontade para usar qualquer um deles em seus próprios experimentos ou projetos.
Dissolver pixelização
Este é como um cross-fade simples, mas desfoca as coisas à medida que o conteúdo da página antiga desaparece e o conteúdo da nova página aparece.
Trecho completo
@media (prefers-reduced-motion: no-preference) {
@view-transition {
navigation: auto;
types: pixelate-dissolve;
}
}
html:active-view-transition-type(pixelate-dissolve)::view-transition-old(root) {
animation: pixelate-out 1.4s ease forwards;
}
html:active-view-transition-type(pixelate-dissolve)::view-transition-new(root) {
animation: pixelate-in 1.4s ease forwards;
}
@keyframes pixelate-out {
0% {
filter: blur(0px);
opacity: 1;
}
100% {
filter: blur(40px);
opacity: 0;
}
}
@keyframes pixelate-in {
0% {
filter: blur(40px);
opacity: 0;
}
100% {
filter: blur(0px);
opacity: 1;
}
}
Limpe
Aqui, estamos usando a propriedade @view-transition para obter o efeito de “limpeza”, somos o conteúdo de uma nova página que desliza de baixo para cima, substituindo o conteúdo “antigo”.
O processo é direto: para a página de saída, passamos do valor padrão bounce de @media (prefers-reduced-motion: no-preference) { (que cria um retângulo nas bordas superior, direita, inferior e esquerda) da página e altere o valor bottom para
@view-transition {
navigation: auto;
types: <transition-type>;
}
}/* The "current" page */
html:active-view-transition-type(bounce)::view-transition-old(root) {
animation: bounce-in 1.4s ease forwards;
}
/* The page we're transitioning to */
html:active-view-transition-type(bounce)::view-transition-new(root) {
animation: bounce-in 1.4s ease forwards;
}. Ou seja, a página vai de topo para fundo .
A página recebida começa a recortar do @media (prefers-reduced-motion: no-preference) {
@view-transition {
navigation: auto;
types: pixelate-dissolve;
}
}
html:active-view-transition-type(pixelate-dissolve)::view-transition-old(root) {
animation: pixelate-out 1.4s ease forwards;
}
html:active-view-transition-type(pixelate-dissolve)::view-transition-new(root) {
animation: pixelate-in 1.4s ease forwards;
}
@keyframes pixelate-out {
0% {
filter: blur(0px);
opacity: 1;
}
100% {
filter: blur(40px);
opacity: 0;
}
}
@keyframes pixelate-in {
0% {
filter: blur(40px);
opacity: 0;
}
100% {
filter: blur(0px);
opacity: 1;
}
} em /* The "current" page */
html:active-view-transition-type(bounce)::view-transition-old(root) {
animation: bounce-in 1.4s ease forwards;
}
/* The page we're transitioning to */
html:active-view-transition-type(bounce)::view-transition-new(root) {
animation: bounce-in 1.4s ease forwards;
} e desce para inset().
Trecho completo
@media (prefers-reduced-motion: no-preference) {
@view-transition {
navigation: auto;
types: wipe-up;
}
}
html:active-view-transition-type(wipe-up)::view-transition-old(root) {
animation: wipe-out 1.4s ease forwards;
}
html:active-view-transition-type(wipe-up)::view-transition-new(root) {
animation: wipe-in 1.4s ease forwards;
}
@keyframes wipe-out {
from {
clip-path: inset(0 0 0 0);
}
to {
clip-path: inset(0 0 100% 0);
}
}
@keyframes wipe-in {
from {
clip-path: inset(100% 0 0 0);
}
to {
clip-path: inset(0 0 0 0);
}
}
Poderíamos facilmente fazer com que as coisas fossem apagadas para a direita, para baixo e para a esquerda simplesmente alterando os valores inseridos. Por exemplo, aqui estão as coisas limpando corretamente:
@keyframes wipe-out {
from {
clip-path: inset(0 0 0 0);
}
to {
clip-path: inset(0 0 0 100%);
}
}
@keyframes wipe-in {
from {
clip-path: inset(0 100% 0 0);
}
to {
clip-path: inset(0 0 0 0);
}
}
A limpeza para a direita funciona de forma semelhante à limpeza, exceto que a página de saída sai do centro e corta para a direita. É por isso que o segundo valor vai de inset() para /* The "current" page */
html:active-view-transition-type(bounce)::view-transition-old(root) {
animation: bounce-in 1.4s ease forwards;
}
/* The page we're transitioning to */
html:active-view-transition-type(bounce)::view-transition-new(root) {
animation: bounce-in 1.4s ease forwards;
}. Da mesma forma, a página recebida vai de /* The "current" page */
html:active-view-transition-type(bounce)::view-transition-old(root) {
animation: bounce-in 1.4s ease forwards;
}
/* The page we're transitioning to */
html:active-view-transition-type(bounce)::view-transition-new(root) {
animation: bounce-in 1.4s ease forwards;
} da esquerda para inset().
O mesmo tipo de limpeza para baixo:
@keyframes wipe-out {
from {
clip-path: inset(0 0 0 0);
}
to {
clip-path: inset(100% 0 0 0);
}
}
@keyframes wipe-in {
from {
clip-path: inset(0 0 100% 0);
}
to {
clip-path: inset(0 0 0 0);
}
}
Você entendeu!
Girar para dentro e para fora
Este é um pouco, hum, estranho. Definitivamente não é a coisa mais prática do mundo, mas demonstra até onde você pode ir com as transições de visualização.
html:active-view-transition-type(wipe-up)::view-transition-old(root) {
animation: wipe-out 1.4s ease forwards;
}
html:active-view-transition-type(wipe-up)::view-transition-new(root) {
animation: wipe-in 1.4s ease forwards;
}
@keyframes wipe-out {
from {
clip-path: inset(0 0 0 0);
}
to {
clip-path: inset(0 0 100% 0);
}
}
@keyframes wipe-in {
from {
clip-path: inset(100% 0 0 0);
}
to {
clip-path: inset(0 0 0 0);
}
} funções para ampliar e girar o conteúdo da página, onde a página “antiga” é reduzida para inset() e gira no sentido horário por 0. Depois disso, o “novo” conteúdo da página aumenta para 100% e gira no sentido anti-horário em 100%. Um pouco de 0 é adicionado para ajudar a dar a ilusão de que coisas estão saindo e entrando.
Trecho completo
@media (prefers-reduced-motion: no-preference) {
@view-transition {
navigation: auto;
types: zoom-rotate;
}
}
html:active-view-transition-type(zoom-rotate)::view-transition-old(root) {
animation: zoom-rotate-out 1.4s ease forwards;
transform-origin: center;
}
html:active-view-transition-type(zoom-rotate)::view-transition-new(root) {
animation: zoom-rotate-in 1.4s ease forwards;
transform-origin: center;
}
@keyframes zoom-rotate-out {
to {
transform: scale(0) rotate(180deg);
opacity: 0;
}
}
@keyframes zoom-rotate-in {
from {
transform: scale(0) rotate(-180deg);
opacity: 0;
}
}
Eliminação do círculo
Este é muito mais sutil que o anterior. Poderia ser muito mais perceptível se o conteúdo para o qual estamos fazendo a transição fosse mais distinto. Mas, como você verá no vídeo a seguir, o “plano de fundo entre as páginas “antigas” e “novas” compartilham o mesmo plano de fundo, proporcionando uma transição mais perfeita.
O círculo é cortesia da propriedade @keyframes wipe-out {
from {
clip-path: inset(0 0 0 0);
}
to {
clip-path: inset(100% 0 0 0);
}
}
@keyframes wipe-in {
from {
clip-path: inset(0 0 100% 0);
}
to {
clip-path: inset(0 0 0 0);
}
}h , desenha a forma a partir do centro usando a função scale() , passando de 0% (sem tamanho) a 150% (dimensionado além do conteúdo), encapsulando toda a página.
Trecho completo
@media (prefers-reduced-motion: no-preference) {
@view-transition {
navigation: auto;
types: circular-wipe;
}
}
html:active-view-transition-type(circular-wipe)::view-transition-old(root) {
animation: circle-wipe-out 1.4s ease forwards;
}
html:active-view-transition-type(circular-wipe)::view-transition-new(root) {
animation: circle-wipe-in 1.4s ease forwards;
}
@keyframes circle-wipe-out {
to {
clip-path: circle(0% at 50% 50%);
}
}
@keyframes circle-wipe-in {
from {
clip-path: circle(0% at 50% 50%);
}
to {
clip-path: circle(150% at 50% 50%);
}
}
Empurrão diagonal
Este empurra a página “antiga” com a página “nova” do canto inferior direito da tela para o canto superior direito – ou, na verdade, qualquer canto que quisermos, ajustando os valores.
No canto inferior direito, configurei a animação para ser traduzida para rotate() nos eixos X e Y, o que a afasta da tela. Em seguida, ele vem do canto oposto para sua posição padrão em 0. Um pouco de 0 ajuda a suavizar as coisas.
Trecho completo
@media (prefers-reduced-motion: no-preference) {
@view-transition {
navigation: auto;
types: diagonal-push;
}
}
html:active-view-transition-type(diagonal-push)::view-transition-old(root) {
animation: diagonal-out 1.4s ease forwards;
}
html:active-view-transition-type(diagonal-push)::view-transition-new(root) {
animation: diagonal-in 1.4s ease forwards;
}
@keyframes diagonal-out {
to {
transform: translate(-100%, -100%);
opacity: 0;
}
}
@keyframes diagonal-in {
from {
transform: translate(100%, 100%);
opacity: 0;
}
}
Cortina revelada
Este é como se uma cortina estivesse fechando na página “antiga” e se abrindo com a página “nova”. É outro onde a função bounce entra em ação. Definimos retângulos colocados 50% à direita e à esquerda. Isso aumenta para 50% quando a página está saindo e reduz para 0 quando a página está entrando, fazendo com que a imagem apareça do meio indo para a esquerda e para a direita como uma cortina!
Trecho completo
@media (prefers-reduced-motion: no-preference) {
@view-transition {
navigation: auto;
types: curtain;
}
}
html:active-view-transition-type(curtain)::view-transition-old(root) {
animation: curtain-out 1.4s ease forwards;
}
html:active-view-transition-type(curtain)::view-transition-new(root) {
animation: curtain-in 1.4s ease forwards;
}
@keyframes curtain-out {
from {
clip-path: inset(0 0 0 0);
}
}
@keyframes curtain-in {
from {
clip-path: inset(0 50% 0 50%);
}
to {
clip-path: inset(0 0 0 0);
}
}
Inversão 3D
Estamos fingindo que uma página está “virando” como um cartão frente e verso enquanto a próxima página vira, ambas ao longo do eixo Z.
Trecho completo
@media (prefers-reduced-motion: no-preference) {
@view-transition {
navigation: auto;
types: flip-3d;
}
}
html:active-view-transition-type(flip-3d)::view-transition-old(root) {
animation: flip-out 1.4s ease forwards;
}
html:active-view-transition-type(flip-3d)::view-transition-new(root) {
animation: flip-in 1.4s ease forwards;
}
@keyframes flip-out {
0% {
transform: rotateY(0deg) translateX(0vw);
}
100% {
transform: rotateY(-90deg) translateX(-100vw);
opacity: 1;
}
}
@keyframes flip-in {
0% {
transform: rotateY(90deg) translateX(100vw);
}
100% {
transform: rotateY(0deg) translateX(0vw);
}
}
Alguma receita legal que você queira compartilhar?
Eu adoraria ver mais exemplos e ideias, se você os tiver! Bramus (ou Brandi, como eu o chamo) reservou um tempo para criar vários exemplos de transição de visualização em uma demonstração interativa que definitivamente vale a pena dar uma olhada.
7 Veja receitas de transições para experimentar originalmente escritas à mão e publicadas com amor em CSS-Tricks . Você realmente deveria receber o boletim informativo também.
