Transiciones CSS

Suavizar cambios de estilo en interacciones del usuario


Como vimos en el apartado de selectores, podemos utilizar pseudoclases como :hover para cambiar los estilos cuando el usuario mueva el ratón sobre el elemento HTML que tiene dicha pseudoclase. Esto provoca un cambio de estilo, y le da al usuario la confirmación de que está preparado para confirmar una selección o acceder a una nueva sección.

En CSS aparecen uno de los aspectos más interesantes de una web interactiva: las transiciones. Hasta ahora, al utilizar una pseudoclase como :hover, el cambio de estilos ocurría de golpe, pasando de un estado inicial a otro final. Utilizando transiciones tenemos a nuestra disposición una gran flexibilidad que nos permitirá dotar de atractivos efectos de transición que harán que nuestros diseños sean más elegantes y agradables.

Las transiciones se basan en un principio muy básico: conseguir un efecto suavizado entre un estado inicial y un estado final al realizar una acción.

Propiedades de transición

Las propiedades CSS que podemos utilizar relacionadas con las transiciones son las siguientes:

Propiedades Descripción Valor
transition-duration Tiempo de duración. 0 |
transition-property Propiedades CSS afectadas por la transición. all | none | propiedad css
transition-timing-function Ritmo de la transición. Ver funciones de tiempo
transition-delay Tiempo de retardo inicial. 0 |

Ten en cuenta que por defecto las transiciones están habilitadas para todas las propiedades CSS involucradas. Sin embargo, tienen una duración de 0s. Salvo que cambiemos esta duración, no se realizará transición.

Veamos como funciona cada una de estas propiedades detalladamente:

La propiedad transition-duration

Con la propiedad transition-duration especificaremos la duración de la transición, desde el inicio de la transición, hasta su finalización. Recuerda que por defecto, las transiciones tienen una duración de 0s, por lo que si no cambias este valor, cambiará de golpe y será lo mismo que no tener transición.

.element {
  transition-duration: 0.5s;
  width: 200px;
  height: 200px;
  background: grey;
}

.element:hover {
  background: indigo;
}
<div class="element"></div>

Ojo: Si establecemos una duración demasiado alta, el navegador realizará la transición a trozos intermitentes, lo que hará que se vea a golpes. Se recomienda siempre comenzar con valores cortos, para que las transiciones sean rápidas y elegantes.

La propiedad transition-property

En primer lugar, la propiedad transition-property se utiliza para especificar la propiedad a la que que afectará la transición. Podemos especificar la propiedad concreta (width o color, por ejemplo) o simplemente especificar all para que se aplique a todos los elementos con los que se encuentre. Por otro lado, none hace que no se aplique ninguna transición.

Propiedades Valor
all Aplica la transición a todas las propiedades css.
none No aplica transición. El cambio se producirá de golpe (brusco).
propiedad css Aplica la transición sólo a la propiedad css especificada.

Ten en cuenta que para la transición se efectue correctamente, deberíamos tener un estado inicial y un estado final, en caso contrario, el navegador podría no saber uno de esos estados y por lo tanto, no podría efectuar la transición. En algunos casos no será necesario el estado inicial puesto que tomará el valor por defecto en ese caso.

Ten en cuenta que puedes animar todas las propiedades CSS afectadas utilizando all:

.element {
  /* Primer ejemplo: Anima todas las propiedades que cambien de estado */
  transition-property: all;
  transition-duration: 1s;

  /* Segundo ejemplo: Anima sólo el ancho, el resto no transicionan, cambian de golpe */
  transition-property: width;
  transition-duration: 1s;
}

Nota: Debes saber que no todas las propiedades CSS son animables (o transicionables). Por norma general, la mayoría de las propiedades que son cuantificables (valores numéricos, porcentajes, valores hexadecimales como colores, etc...) son animables, sin embargo, otras propiedades no lo son. Por ejemplo, la propiedad background-image para gradientes no se puede animar actualmente.

La propiedad transition-delay

Por último, la propiedad transition-delay nos ofrece la posibilidad de retrasar el inicio de la transición un número de segundos determinado. Si se omite, la transición comienza inmediatamente.

Veamos un pequeño ejemplo de todas estas propiedades de transición. Utilizaremos la función de tiempo linear, que explicaremos en el próximo capítulo:

a {
  display: inline-block;
  background: #ddd;
  color: #222;
  padding: 8px 16px;

  transition-property: all;
  transition-duration: 0.5s;
  transition-timing-function: linear;
}

a:hover {
  background: #fff;
  color: darkred;
  padding: 32px;
  border: 1px solid darkred;
}
<a href="https://manz.dev/">Manz.dev</a>

En este ejemplo, con all hemos determinado animar todas las propiedades que cambien:

  • La propiedad background de color de fondo cambiará de #ddd a #fff
  • La propiedad color de color de texto cambiará de #222 a #666
  • La propiedad padding del tamaño del relleno cambiará de 8px a 25px
  • La propiedad border cambiará de 0 a 1px solid #888.

Este último es un caso especial, puesto que cambia de estilos porque toma el estilo inicial por defecto, que es un borde de 0px de grosor. Cada una de estas transiciones se realizarán a un ritmo lineal, durante 0.5s de duración.

Atajo: La propiedad transition

Como siempre, podemos resumir todas estas operaciones en una propiedad de atajo denominada transition. Los valores del ejemplo superior, se podrían escribir como se puede ver a continuación (si no necesitas algún valor, se puede omitir):

.box {
  /* transition: <property> <duration> <timing-function> <delay> */
  transition: all 0.5s linear;

  background: grey;
  width: 200px;
  height: 200px;
}

.box:hover {
  background: indigo;
}
<div class="box"></div>

Observa que estamos omitiendo el último valor. Si quisieramos un retardo de 2s a la hora de hacer una transición, bastaría con añadir un 2s después de linear.

Si quieres ver un ejemplo real de uso de transiciones, en el siguiente video explico como hacer la animación de la cabecera de Manz.dev utilizando transiciones:

Transiciones de entrada y salida

Aprovechando la cascada de CSS, podemos hacer transiciones de entrada y salida diferentes.

Si nos fijamos bien, la transición del ejemplo anterior se aplica sólo al mover el ratón sobre el elemento (transición de entrada). Sin embargo, si movemos el ratón fuera del enlace, no se produce transición, sino que realiza el cambio de forma brusca. Esto ocurre porque le estamos diciendo que solo realice la transición cuando tenemos el ratón encima (:hover), en caso contrario no lo hará porque no hay definidas propiedades de transición.

Si movemos las propiedades de transición al primer bloque, se aplicarán tanto en las transiciones de entrada como en las transiciones de salida. Por otro lado, si indicamos unas propiedades transition-* en a y otras en a:hover con diferentes valores, podremos conseguir (por ejemplo) duraciones diferentes.

a {
  background: black;
  color: white;
  padding: 8px;
  transition: background 0.2s linear;
}

a:hover {
  background: red;
  transition: background 2s linear;
}

En este caso, cuando mueves el ratón encima del enlace, la transición tardará 2 segundos en ponerse en rojo. Sin embargo, cuando quitemos el ratón del elemento, se producirá en 0.2 segundos ya que se efectua la transición del primer bloque.

¡Recuerda siempre tener cuidado con la herencia, cascada y especificidad!

Transiciones diferentes

También es posible que queramos indicar, por ejemplo, diferentes duraciones dependiendo de la propiedad CSS. Por ejemplo, que tarde mucho en cambiar el ancho del elemento, pero muy poco en cambiar el color de fondo.

Para ello, podemos separar con comas las diferentes propiedades que queremos transicionar:

.box {
  width: 200px;
  height: 200px;
  background: grey;
  transition:
    width 3s,
    background-color 0.5s;
}

.box:hover {
  width: 400px;
  background: deeppink;
}
<div class="box"></div>

De esta forma, la transición de la propiedad width tardará 3 segundos en cambiar, mientras que la del color de fondo tardará sólo 0.5s.

¿Quién soy yo?

Soy Manz, vivo en Tenerife (España) y soy streamer partner en Twitch y profesor. Me apasiona el universo de la programación web, el diseño y desarrollo web y la tecnología en general. Aunque soy full-stack, mi pasión es el front-end, la terminal y crear cosas divertidas y locas.

Puedes encontrar más sobre mi en Manz.dev