Pular para o conteúdo
~/.primo-academy.sh
☰ Aulas · CSS · 0/36
Recomendado: essencial

Animações: @keyframes e animation

2 min de leitura

fonte

Transição é "de A para B quando algo mudar". Animação é "rode essa sequência de estados automaticamente, com quantos passos eu quiser, quantas vezes eu quiser". Para coisas como loader, attention-grabbers, entrada de elementos na tela - animação é a ferramenta certa.

@keyframes: definindo a sequência

@keyframes pulsar {
  0%   { transform: scale(1);   opacity: 1; }
  50%  { transform: scale(1.2); opacity: 0.7; }
  100% { transform: scale(1);   opacity: 1; }
}

.alerta {
  animation: pulsar 1.5s ease-in-out infinite;
}

@keyframes é uma "tabela de estados ao longo do tempo". Você define percentuais (0%, 50%, 100% são os principais; pode usar qualquer valor como 17% ou 73%). O navegador interpola entre os estados declarados.

Shorthand animation

animation: <nome> <duração> <curva> <delay> <contagem> <direção> <fill-mode> <play-state>

Exemplos:

/* Pulsar pra sempre (loader) */
.loader { animation: girar 1s linear infinite; }

/* Uma vez, no carregamento da página */
.aparecer { animation: aparecer 0.3s ease-out 1; }

/* Duas vezes, com delay */
.chamar-atencao { animation: chamar 0.5s ease-in-out 2 0.5s; }
/*                                  duração  curva  n  delay */

/* Piscar só uma vez, sem repetir */
.toast { animation: sumir 4s ease-out 1 forwards; }

Cada parte da shorthand

animation-name: o nome do @keyframes (sem o @).

animation-duration: quanto tempo dura UM ciclo. Padrão: 0s.

animation-timing-function: mesma curva da transition (ease, linear, cubic-bezier(), etc). Padrão: ease.

animation-delay: espera antes de começar. Útil para escalonar vários elementos.

animation-iteration-count: quantas vezes repete. Número (2), ou infinite. Padrão: 1.

animation-direction: a direção do ciclo.

  • normal (default): 0% → 100%.
  • reverse: 100% → 0%.
  • alternate: 0% → 100% → 0% → 100% (vai e volta). Perfeito para "vai e volta" sem ter que duplicar keyframes.
  • alternate-reverse: começa voltando.

animation-fill-mode: o que acontece antes e depois da animação. O detalhe que pega muita gente.

  • none (default): antes e depois, o elemento fica no estado "neutro" (sem efeito da animação).
  • forwards: depois do último ciclo, fica no último keyframe. Essencial para "entrada" - sem isso, o elemento volta pro estado original.
  • backwards: durante o delay, fica no estado do primeiro keyframe.
  • both: forwards + backwards.
.aparecer {
  opacity: 0;
  transform: translateY(20px);
  animation: entrar 0.5s ease-out forwards;
}

@keyframes entrar {
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

Sem forwards, o elemento volta a ficar invisível depois da animação terminar. Com forwards, ele fica visível.

animation-play-state: running ou paused. Pode ser animado com hover, por exemplo:

.spinner { animation: girar 1s linear infinite; }
.spinner:hover { animation-play-state: paused; }

Animando várias propriedades

Tudo dentro do @keyframes interpola. Você pode animar cor, posição, opacidade, transform, etc - tudo no mesmo keyframe:

@keyframes aparecer {
  0%   { opacity: 0; transform: translateY(20px) scale(0.95); }
  100% { opacity: 1; transform: translateY(0)    scale(1); }
}

Animando propriedade por propriedade (granular)

Para um controle fino, você pode dar durações diferentes:

.modal {
  opacity: 0;
  transform: scale(0.9);
  transition: opacity 0.2s, transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.modal.ativo { opacity: 1; transform: scale(1); }

Isso é mistura de transição + classe de estado, não @keyframes, mas muitas vezes é o que você quer. Animação fica para "cenas" autônomas; transição para "feedback" interativo.

Performance

Animações em transform e opacity são baratas (o navegador acelera por GPU). Em width, height, top, left, margin, background-position (sem ser cover/contain) - caras (forçam recalcular layout).

Regra prática: anime o que é "superficial" (posição, escala, rotação, opacidade). Evite animar tamanho ou posição de elementos que afetam o fluxo.

prefers-reduced-motion

De novo (e nunca é demais): respeite. Animações longas, rápidas ou constantes podem ser problemáticas para pessoas com sensibilidade a movimento.

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}
  • @keyframes define a sequência.
  • animation: nome dur curva delay n dir fill junta tudo.
  • forwards mantém o último frame (essencial para entrada).
  • infinite para loops (loader, atenção).
  • alternate para "vai e volta" sem duplicar.
  • Anime transform e opacity (barato). Evite width/height.

Dica: animação boa é sutil. Pulsar 1.2x é legal. Pulsar 1.5x 5 vezes por segundo é irritante. Animação é tempero, não comida - se o usuário percebeu e ficou olhando, é demais.

No próximo nó, vamos mergulhar no transform - a propriedade responsável por translate, rotate, scale e o mundo 3D que o CSS permite.

// recursos

// avaliação da trilha

ainda sem avaliações