1. Web Design
  2. HTML/CSS

Animaciones CSS3: Los hipo y los errores que querrás evitar

Scroll to top
10 min read

Spanish (Español) translation by Steven (you can also view the original English article)

La animación CSS3 es bastante genial. Nos permite dar vida acelerada al hardware a nuestros sitios web que antes eran aburridos. Sin embargo, hay algunas trampas y prácticas importantes que debes tener en cuenta: profundicemos.

El soporte del navegador para la animación CSS3 se está calentando: Mozilla Firefox se ha unido a WebKit en soporte completo, e Internet Explorer 10 y Opera 12 han prometido soporte a futuro. Esto significa que podemos empezar a utilizarlos hoy sin miedo. Sin embargo, este próspero apoyo no está exento de problemas.


No son los androides que estamos buscando

Al ser una propiedad nativa de Webkit, esperaría que la animación CSS tenga soporte completo en todos los navegadores Webkit. Desafortunadamente, no es tan simple. El navegador integrado en los dispositivos Android admite animaciones, hasta cierto punto. El problema es que solo admitirá animaciones con una única propiedad cambiante.

Digamos que vamos a trabajar con mi framework de animaciones, Animate.css, para hacer un sitio web genial. La mayoría de las animaciones como bounceInLeft funcionarán muy bien en los últimos Chrome, Safari, Firefox y iOS Safari. Pero en un dispositivo Android, el usuario no verá un solo elemento animado. La animación se ejecuta, pero el elemento desaparece tan pronto como termina.

Esta extraña peculiaridad significa que las únicas animaciones que podemos ejecutar en dispositivos Android son las de una sola propiedad, como fadeIn y bounce. Desafortunadamente, no está claro si Android 4.0 brindará un mejor soporte, con suerte lo hará.

The Animatecss home page shows absolutely nothing on Android devices

Hasta que veamos un mayor soporte de estos dispositivos Android, lo mejor que puede hacer es proporcionar resguardos de Javascript o animaciones menos complejas. Pero, ¿cómo puedes decirle a tu sitio que no use tus fantásticas animaciones en estos dispositivos? Usar Modernizr no ayudará aquí: detectará que el navegador admite animaciones. Afortunadamente, podemos verificar el agente de usuario y ofrecer una hoja de estilo o un script alternativo. En PHP, es tan fácil como esto:

1
$ua = strtolower($_SERVER['HTTP_USER_AGENT']);
2
if(stripos($ua,'android') !== false) { // && stripos($ua,'mobile') !== false) {

3
	$css = "droid-style.css";
4
} else {
5
	$css = "style.css";
6
}

Ese fragmento cargará droid-style.css en dispositivos Android, lo que significa que podemos mantener nuestras animaciones de pantalones elegantes para los navegadores que pueden usarlas. ¡Excelente!


Para 2D, presiona 3D

Los dispositivos iOS como iPhone y iPad tienen un excelente soporte para animaciones CSS3, con aceleración de hardware completa, pero solo si se trata de una transformación 3D. Si la animación no implica una transformación 3D, será acelerada únicamente por el software, lo que puede resultar en animaciones retrasadas.

Para obtener una aceleración de hardware completa en las animaciones, debes activar el motor de renderizado 3D. Eso es tan fácil como agregar esta regla a tu CSS:

1
.container {
2
    -webkit-transform: translateZ(0);
3
}

¡Genial! Pero, ¿por qué no aplicar esta regla al body? Bueno, por alguna razón, la activación del motor 3D juega un poco con el diseño de la página. Los elementos fijos o absolutamente posicionados se desplazarán ligeramente con esto aplicado al 'body'.

Como ocurre con todas las cosas del mundo CSS3, este ingenioso truco tiene un coste. No es considerable, pero sí tiene un costo. Eche un vistazo a esta comparación científica:

Antialiasing screws up with the active 3d rendering engineAntialiasing screws up with the active 3d rendering engineAntialiasing screws up with the active 3d rendering engine

Se necesita un buen ojo para verlo, pero la activación del motor de renderizado 3D hace que el suavizado del texto en escala de grises se traduzca en un texto un poco más nítido y es particularmente notable en tamaños de texto extremadamente pequeños o extremadamente grandes. Como dije, no es gran cosa, pero sigue siendo un error. Añadiendo -webkit-font-smoothing: antialiased; puede ayudar a reducir ligeramente el problema en los navegadores Webkit.


El problema de las transformaciones

Imaginemos que necesitas mover un elemento de un lugar a otro, sin que esto afecte al diseño de la página. translate es tu mejor amigo aquí: la propiedad translate, según la define el W3C:

...no afecta el flujo del contenido que rodea al elemento transformado. Sin embargo, el valor del área de desbordamiento tiene en cuenta los elementos transformados.

¿Ves eso? No afecta el flujo del contenido circundante. Pero afecta el desbordamiento del documento. Esto significa que si mueves un elemento fuera de la página (que es el caso de algunas animaciones en Animate.css), se generarán barras de desplazamiento.

Los navegadores tratan este comportamiento de forma un poco diferente entre ellos. Safari y Chrome crearán barras de desplazamiento, pero luego, una vez que se complete la transformación y la opacidad del elemento se reduzca a cero, eliminará las barras de desplazamiento, como si el elemento se hubiera eliminado. Firefox, por otro lado, crea barras de desplazamiento persistentes que permanecerán hasta que el elemento se elimine del documento o se configure por display: none. La mejor manera de trabajar con estas transformaciones es usar un poco de magia de JavaScript. Si conoces la duración de tu animación, debes eliminar el elemento del DOM una vez que hayas terminado la animación. Alternativamente, puedes observar cuándo se completa la animación con un Javascript inteligente:

1
var element = document.getElementById("#box");
2
element.addEventListener("webkitAnimationEnd", function(){
3
    this.style.webkitAnimationName = "";
4
}, false);
5
document.getElementById("#button").onclick = function(){
6
    element.style.webkitAnimationName = "shake";
7
    // you'll probably want to preventDefault here.

8
};

Este pequeño fragmento en realidad proviene de un hilo de Stack Overflow. Es bueno, ¡así que márcalo como favorito!


Luchando contra el Flash

Si estás escribiendo tu propia animación CSS, es posible que observes algo extraño en los dispositivos Safari, Chrome e iOS. Antes de que se ejecute la animación, el elemento animado en cuestión aparecerá y desaparecerá de la visibilidad justo antes de que comience.

La razón detrás de este fenómeno no está clara, pero la solución es bastante simple. Simplemente agregando la regla -webkit-backface-visibility: hidden; a tu CSS debería ayudar a prevenir el problema. Aplícalo al contenedor del elemento, así:

1
.container {
2
	-webkit-backface-visibility: hidden;
3
}

Todo se reduce a otro problema de aceleración de hardware: El uso de esta propiedad simplemente activa la aceleración. También puedes usar cosas como -webkit-perspective: 1000; u otras propiedades 3D.


Pseudoelementos e índice Z

Aquí hay otro par de verdades desafortunadas con animaciones y transiciones CSS. No puedes usar animaciones o transiciones en pseudo elementos. Este hecho está poco documentado en la web, pero es importante. Digamos, por ejemplo, que deseas que un pseudo elemento :after se desvanezca en la visibilidad cuando se desplaza sobre su elemento principal. Desafortunadamente, cambiará de estado en lugar de realizar una transición elegante. Hasta donde sabemos, este es un comportamiento inusual: hay informes de errores archivados para Chrome y Webkit, y Firefox realmente admite estas transiciones. Puedes mantenerte al día con el estado actual de soporte para transiciones y animaciones en pseudo elementos en CSS-tricks.

Sin embargo, vale la pena señalar que si aplicas transiciones o animaciones a un elemento que tiene pseudo elementos, esas transiciones se llevarán a cabo a los pseudo elementos.

Y ahora otra patada en los dientes. Las transiciones y animaciones restablecen el índice Z de un objeto. Si tienes algunos objetos bien apilados que deseas animar, se restablecerá su orden de apilamiento. Es una verdad desafortunada y, nuevamente, no una de la que mucha gente hable.


Movimiento realista

Puede que me esté metiendo en aguas bastante profundas aquí, pero puedes hacer que tus animaciones sean mucho más realistas jugando con las funciones de sincronización. Si simplemente dejas las funciones de temporización predeterminadas para las animaciones (ease), puedes terminar con algunos efectos bastante agradables. Sin embargo, si estás intentando recrear un patrón de movimiento en particular en CSS, es importante aprender las diferencias entre las diferentes funciones de sincronización. Tomemos la animación 'hinge' de Animate.css como ejemplo.

La idea detrás de esta animación era hacer que el elemento cayera de su posición actual, se balanceara desde una sola esquina por un momento y luego se cayera por completo, algo así como un letrero roto. Aquí está el truco: la animación requerirá una variedad de funciones de sincronización para que sea realista. Piensa en este movimiento en la vida real; cuando el letrero cae y comienza a oscilar, comenzará lentamente, luego acelerará y luego disminuirá la velocidad en su punto máximo. Sin embargo, cuando cae por completo, debería caer bastante repentinamente y acelerarse a medida que cae. Parece que necesitamos tanto ease-in-out como ease-in.

De hecho, es bastante fácil. Dentro de tus fotogramas clave, puedes declarar las diferentes funciones de tiempo, como esta:

1
@keyframes hinge {
2
	0% {
3
		animation-timing-function: ease-in-out;
4
		transform: rotate(-120deg);
5
		transform-origin: top left;
6
	}
7
8
	25% {
9
		animation-timing-function: ease-in-out;
10
		transform: rotate(70deg);
11
		transform-origin: top left;
12
	}
13
14
	50% {
15
		animation-timing-function: ease-in-out;
16
		transform: rotate(-120deg);
17
		transform-origin: top left;
18
	}
19
20
	100% {
21
		animation-timing-function: ease-in;
22
		transform: rotate(0deg) translateY(200%);
23
	}
24
}

Al usar una variedad de funciones de temporización, en lugar de solo la predeterminada, tenemos un mayor control sobre cómo se reproduce la animación. Si ejecutas la animación 'hinge' sin las funciones de temporización personalizadas, puedes ver lo extraño que parece. Al escribir tus animaciones, compáralas con instancias de la vida real del mismo movimiento. Disminuye la velocidad en tu mente y piensa en cómo se cronometra cada una.


No diseñes como si fuera 1999

Esto podría ser lo más importante que te lleves, así que escucha atentamente. Creo firmemente que las animaciones CSS están ahí para usarse con moderación para una mayor interacción, y nada más. Gente inteligente como Anthony Calzadilla están haciendo cosas locas y geniales con animaciones CSS, pero en mi opinión, en el mundo real estas animaciones deberían ser pocas y muy separadas.

Toma esta página como ejemplo. Todo aquí (excepto el gif animado obligatorio) está animado usando CSS. Es un ejemplo extremo, pero puedes ver por qué me preocupa el uso excesivo de estas cosas.

Wow CSS3 gone badWow CSS3 gone badWow CSS3 gone bad

Lo mismo ocurre con todas las propiedades de CSS3. Las transiciones, sombras y degradados deben usarse con sutileza. Creo que la página de aterrizaje de Owlr es un buen ejemplo. Enviar un correo electrónico no válido o un formulario vacío creará un error de validación con un par de animaciones no esenciales para llamar la atención.

Nicely doneNicely doneNicely done

En su libro CSS3 para diseñadores web, (que es una gran lectura), Dan Cederholm habla mucho sobre la "capa de experiencia". Él enfatiza el punto de que todos los valores CSS3 demostrados en su libro son solo para una capa adicional de experiencia: los efectos agregados no son esenciales y siempre deben degradarse con gracia en los navegadores que no los admiten por completo. Recuerda esta regla y te volverás más poderoso de lo que podrías imaginar. O algo así.


Problemas de desempeño

La mayoría de las computadoras tienen potencia más que suficiente para ejecutar animaciones y transiciones CSS3 sin problemas. Sin embargo, cuanto más intentes inyectar en tu CSS, más afectarás el rendimiento.

Tomemos, por ejemplo, una animación simple que mueve un div de izquierda a derecha infinitamente. Cosas simples. Hagamos este cuadro un poco más interesante: dale una sombra de cuadro, una sombra de texto, tal vez un degradado... todas estas reglas afectarán el rendimiento de la página. Si le diste a tu div una sombra de cuadro con un radio de desenfoque ridículo (estoy hablando de cientos aquí), notarás una caída severa en el rendimiento. El navegador está trabajando tan duro tratando de averiguar cómo debería representar los píxeles que forman la sombra del cuadro que comienza a acaparar los recursos necesarios para la animación, o incluso el resto de la página; tareas simples como el desplazamiento pueden volverse dolorosamente lentas. Mantén las mejoras visuales al mínimo, especialmente las sombras.

La aceleración por hardware ayuda a prevenir este problema, pero sigue siendo un problema a tener en cuenta. No todos tus usuarios podrán darse el lujo de la aceleración por hardware, y los gráficos renderizados por software pueden pasar factura a la computadora.


Conclusión

Es de esperar que estés más al tanto de algunos de los escollos de la animación CSS3 y todas sus peculiaridades de navegador cruzado que antes. Pero no olvides que estas funciones de CSS3 siguen siendo muy interesantes y están disponibles para su uso en la actualidad. El soporte es cada vez mayor y señala un mundo en el que podemos alejarnos de Javascript para los efectos visuales, lo cual es una gran cosa si me lo preguntas.

Terminaré con este simple recordatorio:

“Tu contenido y funcionalidad tienen prioridad sobre todo lo demás. Si te encuentras utilizando alguna de las funciones de CSS3, asegúrate de que tu sitio funcione de la misma manera para todos los usuarios sin ellas también".

Recursos adicionales

Si estás cansado de arrancarte los pelos debido a errores confusos, consulta Envato Studio, donde puedes pedir ayuda a desarrolladores seleccionados que aman eliminar errores y hacer correcciones.