ToolHub
View All Posts

Guia de animação CSS: Transições, keyframes e performance

As animações CSS dão vida a as interfaces, proporcionando retroalimentação visual, guiando a atenção do usuário e creando experiências memoraveis. As animações bem feitas se sentem naturales e intuitivas; as mal feitas causan tartamudeo, distraen a os usuarios e inclusive provocan malestar físico. Esta guia cobre todo, desde os fundamentos de transições e keyframes até otimização avanzada de performance e acessibilidade, brindándote o conocimiento para criar animações fluidas, com propósito e inclusivas.

Transições e animações CSS

CSS oferece dois mecanismos distintos para criar movimiento: transições e animações. Compreender quando usar cada um é fundamental para trabalhar eficazmente com animações CSS.

Transições CSS

As transições animan os cambios entre dois estados de uma propriedade CSS. Defines que propriedade animar, a duração e a curva de easing, e o navegador maneja automaticamente a interpolação entre os valores inicial e final. As transições se activan através de cambios de estado como hover, focus, adição de clases o cambios de propriedade desde JavaScript.

.button {
  background: #3b82f6;
  transform: scale(1);
  transition: background 0.3s ease, transform 0.2s ease;
}

.button:hover {
  background: #2563eb;
  transform: scale(1.05);
}

As transições são perfeitas para animações simples de dois estados. Requerem um código mínimo, são fáciles de entender e funcionam de forma confiável em todos os navegadores. A limitação é que solo animan entre dois valores: no podes definir pasos intermedios.

Animações CSS (keyframes)

As animações usam a regra @keyframes para definir uma secuencia de cambios de estilo em qualquer número de pasos. A diferença das transições, as animações podem ejecutarse independientemente dois cambios de estado, repetirse infinitamente, reproducirse em reversa e pausarse. Te dão control preciso sobre cada fotograma da animação.

@keyframes pulse {
  0% {
    transform: scale(1);
    opacity: 1;
  }
  50% {
    transform: scale(1.05);
    opacity: 0.8;
  }
  100% {
    transform: scale(1);
    opacity: 1;
  }
}

.pulse-element {
  animation: pulse 2s ease-in-out infinite;
}

Quando usar cada uma

EscenarioUsar transiçãoUsar animação
Efecto hoverNo
Estado focusNo
Alternar visibilidadePossivelmente
Secuencia de múltiples pasosNo
Animação em bucleNo
Independiente do estadoNo
Animação de entradaPossivelmente

Sintaxe de keyframes em profundidade

A regra @keyframes é o coração das animações CSS. Compreender completamente seu sintaxe desbloquea todo o poder das secuencias de animação de múltiples pasos.

Keyframes basados em percentagem

Os keyframes se definem usando valores porcentuales de 0% a 100%, que representam o progreso na linha de tiempo da animação. Podes definir tantos keyframes como necesites, e o navegador interpola entre eles:

@keyframes bounce {
  0%, 100% {
    transform: translateY(0);
  }
  25% {
    transform: translateY(-20px);
  }
  50% {
    transform: translateY(0);
  }
  75% {
    transform: translateY(-10px);
  }
}

Múltiples keyframes podem compartilhar o mesmo bloque de estilo separando os valores porcentuales com comas, como 0%, 100% no exemplo anterior. Isto é útil para animações que regresan ao estado inicial.

Propriedade abreviada animation

A propriedade abreviada animation combina oito subpropiedades em uma única declaração. O orden é: name, duration, timing-function, delay, iteration-count, direction, fill-mode e play-state.

.element {
  animation: slideIn 0.5s ease-out 0.2s 1 forwards running;
}

/* Equivalent longhand */
.element {
  animation-name: slideIn;
  animation-duration: 0.5s;
  animation-timing-function: ease-out;
  animation-delay: 0.2s;
  animation-iteration-count: 1;
  animation-direction: normal;
  animation-fill-mode: forwards;
  animation-play-state: running;
}

Modos de preenchimento de animação

A propriedade animation-fill-mode controla que estilos se aplican antes e depois de que se ejecute a animação. É uma das propriedades de animação mais malinterpretadas:

Funções de easing

As funções de easing (também chamadas funções de temporização) definem a curva de aceleração de uma animação. Determinan se a animação começa lentamente e logo acelera, começa rápido e logo desacelera, o segue um patrón mais complejo. A função de easing correta faz que a animação se sienta natural; a incorrecta a faz sentir mecánica o abrupta.

Funções de easing integradas

Curvas cubic-bezier

A função cubic-bezier() te permite definir curvas de easing personalizadas com control preciso. Acepta quatro parámetros que representam os pontos de control de uma curva de Bézier cúbica: cubic-bezier(x1, y1, x2, y2). Os valores x representam tiempo (0 a 1), os valores e representam progreso (podem exceder 0-1 para efectos de sobreimpulso).

.element {
  /* Smooth deceleration - great for entrances */
  transition: transform 0.3s cubic-bezier(0.0, 0.0, 0.2, 1.0);

  /* Smooth acceleration - great for exits */
  transition: transform 0.2s cubic-bezier(0.4, 0.0, 1, 1);

  /* Material Design standard easing */
  transition: transform 0.3s cubic-bezier(0.4, 0.0, 0.2, 1);
}

Funções de pasos (steps)

A função steps() crea animações discretas fotograma a fotograma em vez de interpolação suave. É útil para animações de sprites o para criar um efecto de 'escritura':

@keyframes typing {
  from { width: 0; }
  to { width: 100%; }
}

.typing-effect {
  animation: typing 3s steps(40, end);
  overflow: hidden;
  white-space: nowrap;
}

Otimização de performance

As animações fluidas requerem 60 fotogramas por segundo (fps), lo que significa que cada fotograma deve completarse em 16.67 milisegundos. No cumprir este presupuesto provoca tartamudeo visível: vibração de a tela, pérdida de fotogramas e degradação da experiência do usuário. Compreender o pipeline de renderizado do navegador é clave para escrever animações de alto performance.

Pipeline de renderizado

Quando uma propriedade CSS muda, o navegador passa por até três etapas para actualizar a tela:

  1. Estilo: Determina que regras CSS se aplican a que elementos.
  2. Layout: Calcula o tamanho e a posição de cada elemento. Activado por cambios em width, height, margin, padding, top, left, font-size e outras propriedades geométricas.
  3. Paint: Preenche os píxeles de cada elemento. Activado por cambios em cor, background, box-shadow, border-radius e outras propriedades visuales.
  4. Composição: Combina as capas pintadas no orden correto. Solo este passo se ejecuta na GPU. Activado por cambios em transform e opacity.

As animações que solo activan o passo de composição têm o melhor performance porque evitan completamente o layout e o paint. Por isso transform e opacity são o estándar de oro para animações CSS de alto performance.

Propriedades solo de compositor

PropriedadeActiva layout?Activa paint?Composição GPU?
transformNoNo
opacityNoNo
filterNoÀs vezes
top / leftNo
width / heightNo
margin / paddingNo
background-corNoNo
box-shadowNoNo

Uso de will-change

A propriedade will-change le diz ao navegador que propriedades se espera que cambien, permitiéndole otimizar por adelantado promovendo o elemento a seu própria capa do compositor. No entanto, deve usarse com moderação:

/* Apply will-change just before the animation */
.element:hover {
  will-change: transform;
}

/* Remove it after the animation completes */
.element {
  transition: transform 0.3s ease;
}

Os erros comuns com will-change incluem aplicarlo a demasiados elementos (cada capa do compositor consume memoria GPU) e mantenerlo permanentemente (desperdiciando recursos). Uma boa prática é adicionar will-change através de JavaScript justo antes de que comience a animação e eliminarlo quando termine.

Usar Transform em vez de propriedades de layout

A otimização de performance mais eficaz é reemplazar as propriedades que activan o layout com transform:

Regra de performance: Se podes lograr o mesmo efecto visual com transform ou opacity, priorízalos siempre sobre as propriedades que activan layout o paint. Este princípio elimina a maioria dois problemas de performance de animação.

Patrones comuns de animação

Ciertos patrones de animação aparecem repetidamente nas interfaces web. Dominar estes patrones te proporciona um kit de ferramentas para a maioria das necessidades comuns de animação UI.

1. Fade in

A animação de entrada mais simple e versátil. O elemento passa de transparente a opaco:

@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

.fade-in {
  animation: fadeIn 0.4s ease-out forwards;
}

2. Deslizar em direção a acima com fade

Um efecto de entrada mais dinámico que combina movimiento vertical e mudo de opacidade. Isto crea a sensação de que o elemento llega desde abaixo:

@keyframes slideUpFade {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.slide-up {
  animation: slideUpFade 0.5s cubic-bezier(0.4, 0, 0.2, 1) forwards;
}

3. Escala ao hover

Um sutil aumento de escala ao passar o cursor proporciona uma retroalimentação interactiva satisfactoria:

.card {
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.card:hover {
  transform: translateY(-4px) scale(1.02);
  box-shadow: 0 12px 24px rgba(0, 0, 0, 0.15);
}

4. Animação de lista escalonada

Quando aparece uma lista de elementos, estabelecer retrasos de animação escalonados para cada elemento crea um efecto de cascada que guia a mirada:

.list-item {
  opacity: 0;
  transform: translateY(10px);
  animation: slideUpFade 0.3s ease-out forwards;
}

.list-item:nth-child(1) { animation-delay: 0.0s; }
.list-item:nth-child(2) { animation-delay: 0.05s; }
.list-item:nth-child(3) { animation-delay: 0.1s; }
.list-item:nth-child(4) { animation-delay: 0.15s; }
.list-item:nth-child(5) { animation-delay: 0.2s; }

Para listas dinámicas, usa JavaScript para estabelecer animation-delay basado no índice de cada elemento, o usa propriedades personalizadas CSS: style="animation-delay: calc(var(--i) * 0.05s)".

5. Spinner de carga

A rotação continua e suave é o clásico indicador de carga:

@keyframes spin {
  to { transform: rotate(360deg); }
}

.spinner {
  width: 24px;
  height: 24px;
  border: 3px solid rgba(255, 255, 255, 0.2);
  border-top-color: #3b82f6;
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}

Acessibilidade em animações: prefers-reduced-motion

No todos os usuarios se benefician das animações. Para pessoas com trastornos vestibulares, sensibilidade ao movimiento o ciertas condiciones cognitivas, as animações podem causar mareos, náuseas o convulsiones. A media query prefers-reduced-motion te permite respetar a preferência de reducção de animação a nivel de sistema do usuário.

Implementar reducção de animação

O abordagem recomendado é habilitar as animações para usuarios que no têm estabelecida a preferência de reducção de animação:

/* Default: no animation for users who prefer reduced motion */
.element {
  opacity: 1;
  transform: none;
}

/* Only animate for users who have no motion preference */
@media (prefers-reduced-motion: no-preference) {
  .element {
    animation: slideUpFade 0.5s ease-out forwards;
  }
}

Alternativamente, podes deshabilitar animações específicas para usuarios que preferem animação reducida:

.element {
  animation: slideUpFade 0.5s ease-out forwards;
}

@media (prefers-reduced-motion: reduce) {
  .element {
    animation: none;
    opacity: 1;
    transform: none;
  }

  /* Keep functional transitions but shorten duration */
  * {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

Que conservar e que eliminar

Quando os usuarios preferem animação reducida, no todas as animações devem eliminarse. As animações funcionales que transmitem significado o estado devem conservarse, solo simplificadas:

Bibliotecas de animação

Embora as animações CSS manejan a maioria das necessidades UI, as bibliotecas de animação JavaScript oferecem características avanzadas como movimiento basado em física, animações vinculadas ao scroll e orquestação de secuencias complejas.

Bibliotecas CSS-first

Bibliotecas de animação JavaScript

Quando usar JavaScript vs CSS

CSS para animações declarativas simples que responden a cambios de estado. JavaScript para: movimiento basado em física (molas, momento), animações vinculadas ao scroll, secuencias complejas com control de tiempo preciso, parámetros de animação dinámicos calculados em tiempo de execução, o animações que necessitam pausarse, invertirse o arrastrarse programáticamente.

Depuração de animações

Os bugs de animação podem ser sutiles e difíciles de diagnosticar. As ferramentas e técnicas de depuração adequadas fazem o proceso mais eficiente.

Panel de animações de Chrome DevTools

Chrome DevTools inclui um panel de animações dedicado que proporciona potentes capacidades de depuração:

Análisis de performance

Usa o panel Performance em Chrome DevTools para identificar o tartamudeo de animações:

Escenarios comuns de depuração

Trabalhas com CSS? Experimenta nossas ferramentas CSS gratuitas para formatear, minificar e otimizar tuas hojas de estilo para producção.

Formateador CSSMinificador CSS

Perguntas frequentes

Devo usar transições CSS o animações CSS?

As transições CSS são para cambios de estado simples de ponto A a ponto B, como efectos hover, estados de focus e alternar visibilidade. As animações CSS (keyframes) são para secuencias complejas de múltiples pasos, animações em bucle o animações que necessitam ejecutarse independientemente dois cambios de estado. As transições são mais simples; as animações oferecem mais control.

Que propriedades CSS são seguras para animar com buen performance?

As propriedades com melhor performance para animar são transform e opacity, porque podem ser manejadas completamente por o compositor GPU sem necessidade de activar layout o paint. Outras propriedades como width, height, margin e top activan o recálculo do layout, lo qual é costoso. Prioriza siempre transform: translateX() sobre left, e transform: scale() sobre cambios de width/height.

Como fazer acessíveis as animações para usuarios sensíveis?

Usa a media query prefers-reduced-motion para deshabilitar o simplificar animações para usuarios que têm habilitada a configuração de 'reducir animação' em seu sistema operativo. Envolve as animações no essenciais em @media (prefers-reduced-motion: no-preference) e proporciona cambios de estado instantáneos como alternativa para usuarios que preferem animação reducida.

Que é will-change e quando devo usarlo?

will-change é uma propriedade CSS que indica ao navegador que propriedades cambiarán no futuro, permitiéndole otimizar por adelantado. Úsalo com moderação, solo quando observes problemas de performance. Aplícalo antes de que comience a animação e elimínalo quando termine. O uso excesivo de will-change desperdicia memoria GPU e pode perjudicar o performance.

Como depurar animações CSS?

Chrome DevTools proporciona potentes ferramentas de depuração de animações. Abre o panel de animações (no menú Mais ferramentas) para ver todas as animações activas, arrastrar a linha de tiempo, modificar durações e retrasos em tiempo real, e ralentizar as animações a 1/4 de velocidade. Também podes usar o panel Performance para identificar tartamudeo de animações e layout thrashing.