Todo sobre transiciones en CSS

Las transiciones hacen parte del conjunto de herramientas que poseemos como desarrolladores FrontEnd para mejorar la experiencia del usuario dentro de nuestra aplicación Web. Son útiles porque nos permiten animar el cambio de valores en las distintas propiedades de un elemento lo que puede hacerlo más llamativo al usuario e invitarlo a interactuar con él. En este post trataré de cubrir el extenso tema de transiciones con diversos ejemplos adaptados desde la especificación.

Empecemos con un ejemplo simple:

Tenemos un cuadrado simple:

  • html
1
<div id="square1" class="square red"></div>

Y unos estilos asociados a dicho cuadrado:

    Y tenemos una clase adicional que se la asignaremos al cuadrado en un momento x en el tiempo:

    • css
    1
    2
    3
    .black {
    background: black;
    }

    Sin embargo queremos que esto se haga de una manera suave, controlada y agradable al usuario. Por tanto es aquí donde necesitamos hacer uso de las transiciones. Esto lo podemos hacer añadiendo la propiedad transition dentro de la clase que queremos añadir:

    • css
    1
    2
    3
    4
    .black {
    background: black;
    transition: background 2s 0.25s;
    }

    La propiedad transition como la hemos usado en el ejemplo anterior nos permite que el cambio de background de rojo a negro se haga durante 2 segundos (duración) en vez de hacer el cambio instantáneamente, también nos permite indicar que este cambio empiece a ocurrir 0.25 segundos después de que asigne la clase al elemento (delay).
    También existe otra sintaxis alternativa para esto que requiere unas cuantas líneas más, sin embargo es útil conocerla:

    • css
    1
    2
    3
    4
    5
    6
    .black {
    background: black;
    transition-property: background;
    transition-duration: 2s;
    transition-delay: 0.25s;
    }

    Analogamente a los valores que hemos asignado en segundo a la duración y al retraso (delay) podríamos haberlo hecho en milisegundos, para lo cual bastaría con multiplicar por 1000 y añadir ms al final. Por ejemplo:

    • css
    1
    2
    3
    4
    ...
    transition-duration: 2000ms;
    transition-delay: 250ms;
    ...

    Si queremos hacer transiciones sobre más de una propiedad, podemos usar all para indicar que la transición se aplica sobre todas las propiedades posibles:

    • css
    1
    2
    3
    4
    5
    .black {
    background: black;
    color: white;
    transition: all 2s 0.25s;
    }

    Nota: Transition all no es recomendable desde el punto de vista de desempeño (performance) altamente recomendamos no usar transition all a menos que definitivamente quieras aplicar transiciones sobre todo lo que pase con el elemento de la misma manera, por eso a continuación te explico como hacer transiciones específicamente con cada propiedad.

    A veces no deseamos que se hagan transiciones sobre todas las propiedades de la misma manera, la propiedad transition además tiene la característica de permitir especificar la transición de cada propiedad simplemente separándolas por coma. Veamos un ejemplo:

    • css
    1
    2
    3
    4
    5
    6
    .black {
    background: black;
    color: white;
    transition: background 2s 0.25s,
    color 1.5 3s;
    }

    En el ejemplo anterior estamos cambiando el background y el color con distinta duración y distinto retraso (delay). Esto permite tener un control mas granular de exactamente lo que necesitamos animar en cada transición.

    Como habrás notado hasta ahora las transiciones de las que hablamos ocurren de manera lineal, esto quiere decir que el cambio ocurre uniformemente durante el tiempo que dure la transición, sin embargo esta no es la única manera de hacerlo, por ejemplo podemos acelerar el cambio al comienzo y desacelerarlo al final lo que nos dará un tipo diferente de sensación al ver la transición. Para determinar como ocurrirá el cambio, tenemos la propiedad transition-timing-function que puede tomar los siguientes valores:

    • css
    1
    2
    3
    4
    5
    transition-timing-function: linear; // Este es el valor por defecto, no hace falta incluirlo
    transition-timing-function: ease-in; // Significa que al comienzo sea rápido el cambio y que después se ralentice.
    transition-timing-function: ease-out; // Significa que al comienzo sea lento el cambio y que después se acelere.
    transition-timing-function: ease-in-out; // Significa que al comienzo y al final sea rápido el cambio pero en la mitad sea lento
    transition-timing-function: cubic-bezier(0.21,0.3,0.1,0.23); // De acuerdo a los valores se acelera o desacelera en los distintos momentos en que ocurre la transición.

    Pero esta no es la única manera de añadir esta propiedad a las transiciones. También es posible hacerlo directamente en la propiedad transition:

    • css
    1
    2
    3
    4
    .move {
    transform: translateX(500px);
    transition: transform 2s 0.25s ease-in-out;
    }

    Incluso en cada transición sobre las propiedades:

      Miremos en detalle un poco más como funciona la propiedad transition-timing-function cuando toma el valor de cubic-bezier(). Para ello revisemos en que consiste la ecuación de la curva de bezier en la cual se basa esta función.

      Las curvas de bezier son un sistema matemático que desarrollo pierre bezier para el trazado de dibujos de aeronaves y automóviles que se describe como una ecuación que toma cuatro valores para describir la curva:

      Con una ecuación matemática de la siguiente forma:

      Pues bien estos cuatro valores (P0 a P3) son los que describen la transición del movimiento entre el punto inicial y el punto final y con estos se pueden definir completamente diversos tipos de transiciones:

      cubic-bezier(P0, P1, P2, P3); En estos sitios web puedes jugar más con este tipo de transiciones donde puedes ajustar los valores para tener un mayor control en tu transición:

      Debes tener en cuenta que hay propiedades que no son “transicionables” esto quiere decir que no puedes aplicar transiciones a estas propiedades. Para ver una lista de cuales propiedades son “transicionables” y cuales no puedes revisar este link:

      https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animated_properties

      En el siguiente ejemplo se muestra un conjunto de transiciones sobre cubos con distintas transition-timing-function y propiedades, puedes jugar con ellas para evidenciar sus diferencias:

      https://codepen.io/seagomezar/pen/wPbYqe

      Las herramientas para desarrolladores de los navegadores como chrome y firefox nos permiten ralentizar o acelerar las transformaciones para un mejor proceso de debug en ellas, para ello puedes abrir la pestaña animaciones:

      Puedes también usar Javascript para conocer el estado de una transición mediante los siguientes listeners:

      • transitionstart
      • transitionend

      Finalmente algunas consideraciones respecto a las transiciones:

      • Transiciones alrededor de 100ms son instantáneas para los usuarios y difícilmente perceptibles.
      • Transiciones de máximo 1 segundo y mínimo 250ms son buenas y mantiene a los usuario conectados.
      • Mas de 2 segundos es definitivamente una mala idea para transformaciones en sitios web estándar ya que puede desconectar al usuario de lo que pasa.
      • De 250ms a 300ms es el tiempo estándar de la mayoría de animaciones.
      • Las transiciones en general te permite crear experiencias que pasan solo una vez.
      • Si el navegador no soporta transiciones en el peor de los casos siempre se cambia la propiedad.
      • Las transiciones son granulares porque te permiten animar una o dos o x propiedades.

      Eso es todo, espero que este post te sea de utilidad y lo puedas aplicar a algún proyecto que tengas en mente y que simplemente te haya ayudado a entender la naturaleza de las transiciones en CSS. Déjame un comentario si lograste implementarlo, si quieres añadir alguna otra funcionalidad o si tienes alguna duda no dudes en dejarme un comentario en la parte de abajo, recuerda que si te gustó también puedes compartir usando los links a las redes sociales en la parte de abajo.

      Copyrights © 2018 Sebastian Gomez. All Rights Reserved.

      Sobre mí

      sebastianMi nombre es Sebastián Gómez, soy ingeniero de sistemas e Informática y Magister en Ingeniería de Sistemas de la Universidad Nacional de Colombia.

      Actualmente trabajo en Globant como Web UI Developer con énfasis en aplicaciones híbridas y cross compiladas. Soy el organizador del Google Developers Group de Medellín, así que contactame si quieres dar alguna charla o participar actuamente de esta comunidad.

      He participado en una Startup Colombiana llamada SponzorMe al lado de Carlos Rojas y fuí participante de Startup Chile a pesar de no haber continuado con esta startup me apasiona el emprendimiento y me gusta aconsejar y ayudar startups como mentor técnico. También he trabajado en empresas Americanas como StudioHyperset en Estados Unidos y para Measured Medium. Mi interés y mi experiencia es el desarrollo de web y móvil full stack como Front-end con Javascript. Me apasiona desarrollar software, escribir código y enseñar lo que aprendo día a día.

      También he trabajado como profesor en diferentes universidades en Medellín Colombia, con tematicas relacionadas con la Inteligencia Artificial, Bases de datos, programación orientada a objetos, minería de datos, desarrollo de software, desarrollo móvil y desarrollo web.

      Me encanta escribir código rápido y prototipar de una manera accelerada si quieres ver que hago día a día puedes darle un vistazo a mi codepen:  https://codepen.io/seagomezar/.

      Todos los días trato de crear o participar en proyectos, la mayoría open source, así que puede chequear mi GitHub:  https://github.com/seagomezar.

      Mi áreas de investigación académica son: Ingeniería de software, Ingeniería de requisitos, procesamiento del lenguaje natural, Ontologías, Bases De Datos,  Machine Learning, Seguimiento de trayectorias y Modelamiento matemático de formaciones.

      Estas son algunas de mis publicaciones académicas mas recientes: