Uma animação CSS em um exemplo
Uma animação tem duas partes: o @keyframes, que descreve as etapas, e a propriedade animation, que as aplica a um elemento com uma duração. Este card desliza e aparece aos poucos quando a página carrega:
Edite o código (ou mude a duração para 2s) e a prévia recarrega, para você ver o card entrar de novo. O bloco @media (prefers-reduced-motion: reduce) troca os keyframes por um fade simples só para leitores cujo sistema está configurado para reduzir movimento.
Sintaxe do @keyframes
@keyframes pulse {
0% { transform: scale(1); }
50% { transform: scale(1.08); }
100% { transform: scale(1); }
}
fromé o mesmo que0%etoé o mesmo que100%.- Acrescente quantas etapas em porcentagem precisar. Etapas com os mesmos estilos podem dividir uma linha:
0%, 100% { ... }. - Uma propriedade que falta no primeiro ou no último keyframe é animada a partir do valor do próprio elemento, ou até ele.
- O nome (
pulse) é o que você passa paraanimation-name. Ele diferencia maiúsculas de minúsculas e não pode ser uma palavra-chave comonone.
As propriedades de animation
| Propriedade | O que define | Padrão |
|---|---|---|
animation-name | qual @keyframes rodar | none |
animation-duration | duração de um ciclo | 0s |
animation-timing-function | curva de velocidade entre os keyframes | ease |
animation-delay | espera antes do primeiro ciclo (negativo começa no meio) | 0s |
animation-iteration-count | número de ciclos, ou infinite | 1 |
animation-direction | normal, reverse, alternate, alternate-reverse | normal |
animation-fill-mode | estilos antes e depois: none, forwards, backwards, both | none |
animation-play-state | running ou paused | running |
O shorthand as aceita em quase qualquer ordem. A única regra é que o primeiro valor de tempo é a duração e o segundo é o delay:
.loader {
animation: pulse 1.2s ease-in-out 0.2s infinite alternate both;
/* name duration timing delay count direction fill */
}
direction e fill-mode, ao vivo
Escolha uma direção, um fill mode e uma contagem e aperte Play. A caixa percorre 200px até o fim da trilha. O painel diz onde ela ficou depois que a animação terminou:
O que observar:
fill-mode: none(o padrão): depois do último quadro, a caixa volta de uma vez para x = 0 e fica âmbar de novo.forwards: ela fica no último keyframe. Comnormal, isso é x = 200 e verde; comreverse, ela termina em x = 0 e azul, porque o último keyframe tocado foi ofrom.alternatecom contagem 2 vai e volta, então até comforwardstermina em x = 0.
Loops infinitos: um indicador de carregamento
infinite repete para sempre, e um animation-delay em cada filho os desencontra para se moverem em sequência. Mantenha os loops calmos: lentos, pequenos, sem piscar.
role="status" com um aria-label avisa a quem usa leitor de tela que algo está carregando, o que os pontos sozinhos não dizem. Para um círculo girando, veja a página de rotate.
Pausar e controlar animações
animation-play-state: paused congela uma animação onde ela está, e running continua dali. Passe o mouse sobre a barra abaixo para pausá-la:
Pelo JavaScript, element.getAnimations() devolve as animações CSS em andamento, cada uma com pause(), play(), cancel() e um currentTime que você pode ler ou definir. O evento animationend dispara quando uma animação não infinita termina, e animationiteration no fim de cada ciclo.
Respeite o movimento reduzido e nunca pisque
Duas regras de acessibilidade valem para toda animação:
- Movimento reduzido. As pessoas podem pedir ao sistema menos movimento porque o movimento lhes faz mal. O padrão mais seguro é só acrescentar movimento quando elas não pediram menos:
@media (prefers-reduced-motion: no-preference) {
.hero-title { animation: slide-in 0.8s ease-out both; }
}
- Nada de piscar. Conteúdo que pisca mais de três vezes em um segundo pode provocar convulsões. Evite de vez piscadas rápidas e de alto contraste.
Mantenha as animações suaves
Anime transform e opacity sempre que puder. O navegador consegue aplicá-las sem montar a página de novo, então elas continuam suaves até em celulares lentos. Animar width, height, top, left ou margin recalcula o layout a cada quadro. Para mover um elemento, use translate(), da página do transform.
Erros comuns
- Sem duração.
animation: fade;não faz nada, porque a duração padrão é0s. - Um nome que não bate. O
animation-nameprecisa ser exatamente igual ao nome do@keyframes, incluindo maiúsculas e minúsculas. - Voltar de uma vez no fim. Acrescente
forwards(ouboth) para manter o último keyframe. - Um piscar antes de uma animação com delay começar. Durante o
animation-delay, o elemento mostra os estilos normais.backwards(ouboth) aplica o primeiro keyframe durante o delay. - Reiniciar uma animação definindo o mesmo valor. Definir o mesmo
animationde novo não faz nada. Remova, force um reflow (el.offsetWidth) e defina de novo, como faz o botão Play acima. - Animar o
display. Ele troca de uma vez. Animeopacityetransform.
Perguntas frequentes
Como fazer uma animação no CSS?
Defina as etapas com @keyframes name { from { ... } to { ... } } e aplique ao elemento com a propriedade animation e uma duração: animation: name 1s ease-out;. A duração é obrigatória, porque o padrão dela é 0s.
O que animation-fill-mode: forwards faz?
Mantém os estilos do último keyframe depois que a animação termina. Sem ele, o elemento volta de uma vez aos estilos normais. backwards aplica o primeiro keyframe durante o delay, e both faz os dois.
Como fazer uma animação CSS em loop infinito?
Defina animation-iteration-count: infinite ou acrescente infinite ao shorthand: animation: spin 1s linear infinite;. Acrescente alternate para tocar para frente e depois para trás a cada ciclo.
Qual a diferença entre animation e transition no CSS?
Uma transition anima uma propriedade entre dois valores quando ela muda, normalmente no hover ou na troca de uma classe. Uma animation roda sozinha assim que é aplicada, pode ter qualquer número de keyframes e pode se repetir, inverter e pausar.
Como pausar uma animação CSS?
Defina animation-play-state: paused no elemento, por exemplo no :hover ou por uma classe acrescentada pelo JavaScript. Voltar para running continua de onde parou.
Como desligar animações para quem prefere movimento reduzido?
Envolva a animação em @media (prefers-reduced-motion: no-preference) { ... } ou remova-a dentro de @media (prefers-reduced-motion: reduce) { ... }. A query segue a configuração de reduzir movimento do sistema operacional do usuário.