Animações CSS
Transições ensinaram A → B num gatilho. Transforms ensinaram para onde vai a caixa pintada. Animações escrevem uma linha do tempo: pulsar um ponto de status, girar um loader sem parar, entrar cartões em sequência — com @keyframes para os passos e animation para executar.
O que é uma animação
Duas partes: um conjunto de keyframes nomeado (@keyframes) que lista estilos em percentagens (ou from / to), e uma regra que reproduz esse nome com duração, atraso opcional, contagem de iterações, direção, função de timing e fill-mode. O navegador interpola entre os pontos keyframe.
A correspondência de nomes é rígida: animation-name: pulse só corre se existir @keyframes pulse. Renomeie um sem o outro e nada se move.
Controles de animação em resumo
📊 Peças centrais da animação
| Peça | Função |
|---|---|
@keyframes name { … } |
Linha do tempo de valores de propriedades em % / from / to |
animation-name |
Qual conjunto de keyframes reproduzir |
animation-duration |
Quanto dura um ciclo (s ou ms) |
animation-timing-function |
Easing dentro do ciclo (ease, linear, …) |
animation-delay |
Espera antes do primeiro ciclo |
animation-iteration-count |
Quantos ciclos (number ou infinite) |
animation-direction |
normal, reverse, alternate, alternate-reverse |
animation-fill-mode |
Estilos antes/depois (none, forwards, backwards, both) |
animation shorthand |
name → duration → timing → delay → iteration → direction → fill-mode (ordem comum) |
Raramente precisa de todos os longhands de uma vez. Comece com name + duration; acrescente infinite para loaders, alternate para ir e voltar, e forwards quando a última keyframe deve ficar.
Primeira linha do tempo — um pulse calmo
Opacity e transform continuam paint-friendly. Um pulse suave é um clássico primeiro exercício de @keyframes.
@keyframes pulse {
0%,
100% {
opacity: 1;
transform: scale(1);
}
50% {
opacity: 0.55;
transform: scale(0.92);
}
}
.status-dot {
display: inline-block;
width: 0.75rem;
height: 0.75rem;
border-radius: 50%;
background: #16a34a;
animation: pulse 1.4s ease-in-out infinite;
}
0% e 100% coincidem para a volta fechar limpa. infinite mantém o ciclo — bom para um indicador pequeno, ruidoso se animar o hero inteiro da página.
Giro infinito — loaders adoram linear
Rotação com linear e infinite lê-se como spinner contínuo. Combine com fallback reduced-motion que esconde ou congela o giro.
@keyframes spin {
to {
transform: rotate(360deg);
}
}
.loader {
width: 2rem;
height: 2rem;
border: 3px solid #e5e7eb;
border-top-color: #2563eb;
border-radius: 50%;
animation: spin 0.8s linear infinite;
}
@media (prefers-reduced-motion: reduce) {
.loader {
animation: none;
border-top-color: #e5e7eb;
}
}
to é atalho para 100%. Começar no 0% padrão (sem transform) basta quando só importa o fim da volta.
Delay e stagger — mesmas keyframes, arranques diferentes
Um conjunto keyframe pode mover vários elementos. Escalone com animation-delay para a lista parecer sequencial sem escrever três animações diferentes.
@keyframes fade-up {
from {
opacity: 0;
transform: translateY(0.75rem);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.reveal-list li {
opacity: 0;
animation: fade-up 0.45s ease forwards;
}
.reveal-list li:nth-child(1) { animation-delay: 0s; }
.reveal-list li:nth-child(2) { animation-delay: 0.08s; }
.reveal-list li:nth-child(3) { animation-delay: 0.16s; }
forwards mantém os estilos da keyframe final depois do ciclo — sem isso, os itens podem voltar de repente a opacity: 0 da regra base. É aí que animation-fill-mode faz trabalho real.
Fill-mode numa entrada única
Movimentos de entrada costumam correr uma vez. Fill-mode decide se estilos aplicam antes do delay e depois do último frame.
@keyframes card-in {
from {
opacity: 0;
transform: translateY(1rem) scale(0.98);
}
to {
opacity: 1;
transform: translateY(0) scale(1);
}
}
.card-enter {
animation: card-in 0.5s ease 0.1s both;
}
Shorthand aqui: name card-in, duration 0.5s, easing ease, delay 0.1s, fill-mode both. both aplica a primeira keyframe durante o delay e segura a última depois.
Direction, play state e quando não animar
animation-direction: alternate faz ciclos ímpares avançar e pares recuar — útil para um bounce suave sem duplicar keyframes. animation-play-state: paused congela animação a correr (útil para pausar no hover em loops decorativos).
Para mudança simples de cor no hover, mantenha transitions. Use animações quando precisar de loops, histórias em vários passos, ou movimento que não depende de um único toggle de estado. Prefira transform e opacity dentro de keyframes; animar width, height ou top pesa mais e muitas vezes treme o layout.
Experimente
- Construa um pulse com três paragens (
0%/50%/100%) só em opacity; depois acrescente umscalepequeno. - Faça um spinner com
spin+linear+infinite; mude paraeasee note a sensação irregular. - Escalone três badges com as mesmas keyframes
fade-upe delays0s,0.1s,0.2s— compare com e semforwards. - Use shorthand
animation: card-in 0.5s ease 0.15s bothnum painel; removabothe veja o snap-back. - Em
prefers-reduced-motion: reduce, definaanimation: none(ou um fade curto) em loops decorativos.
Erros comuns
- Esperar que um fade A→B no hover « faça loop » — isso é território de animação, não de transição solitária
- Typo entre
animation-namee nome@keyframes— silêncio total, nada move infiniteem zonas grandes e chamativas sem pausa ou caminho reduced-motion- Animar propriedades de layout (
width,margin,top) quando transform/opacity bastariam - Omitir
forwards/bothem reveals one-shot que começam deopacity: 0na regra base
Resumo
@keyframesdefinem a linha do tempo;animation(ou longhands) reproduzem- Iteração, direção, delay e fill-mode para loops, bounce-back, stagger e fins que ficam
- Prefira transform/opacity; respeite prefers-reduced-motion em movimento decorativo
- Transitions para mudanças de estado simples; animações para multi-passo e repetição
- Seguinte em Effects & Motion: CSS Filters
🧠 Teste Seu Conhecimento
Teste Seu Conhecimento
Desafie-se com este questionário interativo e veja o quão bem você entende o tópico
📝 Instruções
- Leia cada pergunta cuidadosamente
- Selecione a melhor resposta para cada pergunta
- Você pode refazer o quiz quantas vezes quiser
- Seu progresso será mostrado no topo