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
| Escenario | Usar transição | Usar animação |
|---|---|---|
| Efecto hover | Sí | No |
| Estado focus | Sí | No |
| Alternar visibilidade | Sí | Possivelmente |
| Secuencia de múltiples pasos | No | Sí |
| Animação em bucle | No | Sí |
| Independiente do estado | No | Sí |
| Animação de entrada | Possivelmente | Sí |
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:
- none (predeterminado): O elemento vuelve a seu estilo previo a a animação quando esta termina.
- forwards: O elemento conserva o estilo do último fotograma depois de que termine a animação. Esencial para animações de entrada onde queres que o elemento permanezca em seu posição final.
- backwards: Durante o retraso da animação (antes de que comience), o elemento aplica o estilo do primer fotograma.
- both: Combina o comportamento de forwards e backwards. O elemento muestra o primer fotograma durante o retraso e conserva o último fotograma ao completarse.
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
- linear: Velocidade constante durante toda a animação. Rara vez se vê natural porque os objetos do mundo real no se mueven a velocidade constante. Adequado para animações mecánicas o de rotação.
- ease (predeterminado): Começa lento, acelera no medio, desacelera no final. Um buen easing de propósito general para a maioria das transições UI.
- ease-in: Começa lento e logo acelera. Crea uma sensação de 'acumular impulso'. Adequado para elementos que saem de a tela o caen.
- ease-out: Começa rápido e logo desacelera. Crea uma sensação de 'asentarse'. O easing mais comum para elementos UI que entran na tela.
- ease-in-out: Começo e final lentos, mais rápido no medio. Similar a ease mas com aceleração e desaceleração mais pronunciadas. Adequado para transições mais grandes e dramáticas.
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:
- Estilo: Determina que regras CSS se aplican a que elementos.
- 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.
- Paint: Preenche os píxeles de cada elemento. Activado por cambios em cor, background, box-shadow, border-radius e outras propriedades visuales.
- 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
| Propriedade | Activa layout? | Activa paint? | Composição GPU? |
|---|---|---|---|
| transform | No | No | Sí |
| opacity | No | No | Sí |
| filter | No | Sí | Às vezes |
| top / left | Sí | Sí | No |
| width / height | Sí | Sí | No |
| margin / padding | Sí | Sí | No |
| background-cor | No | Sí | No |
| box-shadow | No | Sí | No |
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:
- Usa transform: translateX(100px) em vez de left: 100px
- Usa transform: translateY(50px) em vez de top: 50px
- Usa transform: scale(1.5) em vez de width: 150%; height: 150%
- Usa transform: rotate(45deg) em vez de rotação através de layout
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:
- Eliminar: Animações decorativas, parallax scrolling, carruseles de reproducção automática, efectos de pulso e animações de fundo em bucle.
- Simplificar: As durações de transição devem acortarse a casi instantáneas (0.01ms) em vez de eliminarse completamente, para que os cambios de estado sigan sendo perceptiveis.
- Conservar: Transições de estado funcionales (hover, focus, active), indicadores de progreso e qualquer animação que transmita informação importante.
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
- Animate.css: Colecção de clases de animação CSS preconstruidas. Solo adiciona nombres de clase a os elementos para aplicar animações. Bom para prototipado rápido, mas pode levar a animações genéricas se se abusa.
- Hamburgers: Colecção de transições animadas de iconos de menú hamburguesa, todas implementadas em CSS puro.
Bibliotecas de animação JavaScript
- Framer Motion: Biblioteca de animação para React que oferece uma API declarativa de animação com física de molas, animações de layout e soporte de gestos. A melhor opção para aplicaciones React.
- GSAP (GreenSock): A biblioteca de animação JavaScript mais potente. Oferece control preciso de linha de tiempo, easing complejo, morphing SVG e animações activadas por scroll. Usada por grandes marcas para sites de marketing e experiências interactivas.
- Anime.js: Biblioteca de animação JavaScript leve com uma API limpia. Soporta propriedades CSS, SVG, atributos DOM e objetos JavaScript. Uma boa opção intermedia entre CSS e GSAP.
- Motion One: Biblioteca de animação moderna e leve construída sobre a Web Animations API. Oferece uma API mínima com física de molas e linhas de tiempo.
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:
- Vista de linha de tiempo: Vê todas as animações activas na página com suas durações, retrasos e keyframes.
- Controles de reproducção: Ralentiza as animações a 1/4 de velocidade, pausa o arrastra a linha de tiempo fotograma a fotograma.
- Inspecção de propriedades: Haz clic em uma animação na linha de tiempo para ver as propriedades CSS exatas que se animan e suas valores em cada keyframe.
- Edição ao vivo: Modifica durações, retrasos e easing de animações em tiempo real sem recargar a página.
Análisis de performance
Usa o panel Performance em Chrome DevTools para identificar o tartamudeo de animações:
- Graba um perfil de performance enquanto se ejecutan as animações
- Busca fotogramas que excedan o presupuesto de 16.67ms (se muestran como barras vermelhas no gráfico de fotogramas)
- Verifica se há operações de 'Layout' nos fotogramas de animação, lo que indica propriedades que activan o layout
- Usa a aba 'Rendering' para habilitar 'Paint flashing' (muestra as áreas repintadas em verde) e 'Layer borders' (muestra as capas do compositor)
Escenarios comuns de depuração
- A animação no se ejecuta: Verifica que animation-fill-mode esté configurado correctamente. Sem forwards o both, o elemento vuelve a seu estado previo a a animação. Também verifica que o elemento tenga as dimensiones corretas: transform: scale(0) faz invisível o elemento embora segue existindo.
- A animação tartamudea: Abre o panel Performance para buscar fotogramas largos. Verifica se estás animando propriedades que activan o layout. Muda a transform e opacity.
- O retraso de animação no se sente bem: Recuerda que animation-delay crea um intervalo antes de que comience a animação. Durante este intervalo, o elemento muestra seu estado previo a a animação a menos que se establezca animation-fill-mode: backwards o both.
- A animação funciona em Chrome mas no em Safari: Safari é mais estricto ao analizar a abreviatura animation. Asegúrate de que todos os valores estén no orden correto e no uses características no soportadas.
Trabalhas com CSS? Experimenta nossas ferramentas CSS gratuitas para formatear, minificar e otimizar tuas hojas de estilo para producção.
Formateador CSSMinificador CSSPerguntas 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.