CSS: Trayectos

En CSS existe la posibilidad de animar elementos para que se muevan a lo largo de trayectos o caminos en formato SVG. Esta característica permite definir un recorrido que el elemento seguirá, proporcionado de esta manera una forma poderosa y flexible de crear animaciones complejas y fluidas.

Los trayectos animados también se denominan «motion paths».

Lista de propiedades para crear trayectos animados:

Propiedad Descripción
offset-path Indica el trayecto o camino.
offset-position Indica la posición inicial.
offset-distance Indica la distancia que debe recorrer.
offset-rotate Indica la rotación/orientación del elemento.
offset-anchor Indica el punto de origen del elemento.
offset Abreviatura para crear trayectos animados.

Antes de entrar a conocer los detalles de cada una de estas propiedades, vamos a ver un ejemplo para visualizar el potencial de este tipo de animaciones. Creamos un camino en forma de arco y un elemento rectangular de color naranja que seguirá el trayecto tanto de ida como de vuelta, siguiendo la misma ruta.

Código CSS:

.contenedor {
  border: 1px solid teal;
  height: 200px;
  max-width: 300px;
}

.objeto {
  animation: mueve 2s infinite ease-in-out alternate;
  background: #ff7f2a;
  height: 24px;
  offset-path: path('M-70,-40 C-70,70 70,70 70,-40');
  width: 12px;
}

@keyframes mueve {
  0% { offset-distance: 0%; }
  100% { offset-distance: 100%; }
}

Resultado:

Se puede ver que el rectángulo sigue el trayecto como si fuera un péndulo, de ida y de vuelta, y siempre en perpendicular respecto al arco.

La propiedad ‘offset-path’

La propiedad CSS offset-path permite definir el trayecto o camino que el elemento deberá recorrer durante su animación. Este camino puede ser tan simple como una línea recta, un arco o una figura más compleja, y se puede definir en formato SVG a partir de una serie de funciones muy interesantes.

Valor Descripción
none Sin trayecto por recorrer.
ray() Define un segmento de línea con un ángulo.
url() Define un trayecto con el id de un elemento.
Figuras Define un trayecto con figuras geométricas.

El valor por defecto de esta propiedad es none, con el que el elemento no recorrerá ningún trayecto. En este caso, el movimiento del elemento estará determinado únicamente por sus propiedades de posición.

La función ‘ray()’

La función ray() define una línea que comienza a partir de una posición inicial, con una longitud establecida y se extiende en un ángulo concreto. Esta función admite hasta cuatro parámetros que se pueden introducir en cualquier orden: el ángulo, el tamaño, la palabra clave contain y la posición. Cabe mencionar que esta función trabaja en un espacio de dos dimensiones (2D).

El ángulo es un parámetro obligatorio e indica la dirección en la que se extiende el segmento de línea a partir de la posición inicial. En este sentido, el ángulo que corresponde a los 0 grados se encuentra en el eje vertical apuntando hacia arriba. Los ángulos positivos aumentan en el sentido de las agujas del reloj.

El tamaño es un parámetro opcional para indicar la longitud del segmento de línea. Se trata de la distancia que queda entre los valores 0% y 100% de la propiedad offset-distance, pero en relación con la caja contenedora. Si no se indica valor se usará closest-side por defecto. Valores posibles para el tamaño:

Valor Descripción
closest-side Distancia entre el punto inicial de la línea y el lado más cercano de la caja contenedora.
farthest-side Distancia entre el punto inicial de la línea y el lado más lejano de la caja contenedora.
closest-corner Distancia entre el punto inicial de la línea y la esquina más cercana de la caja contenedora.
farthest-corner Distancia entre el punto inicial de la línea y la esquina más lejana de la caja contenedora.
sides Distancia entre el punto inicial de la línea y el punto donde la línea cruza el límite de la caja contenedora.

La palabra clave contain, del verbo «contener», reduce la longitud del segmento de línea para que el elemento permanezca dentro de la caja contenedora. Así se ajusta en su interior. También se trata de un parámetro opcional.

La posición es un parámetro opcional que permite indicar el punto de inicio del segmento de línea y su ubicación respecto el elemento contenedor (padre). Este parámetro debe ir precedido de la palabra clave at, y tras dejar un espacio se introduce los dos valores referentes a la posición, que pueden ser numéricos relativos, absolutos o las palabras clave de posición.

Veamos algunos ejemplos de uso de la función ray():

.ejemplo {
  offset-path: ray(45deg closest-corner contain at 50% 50%);
}

.ejemplo {
  offset-path: ray(180deg contain);
}

.ejemplo {
  offset-path: ray(200deg at 80px 3em);
}

.ejemplo {
  offset-path: ray(15deg at bottom right);
}

La función ‘url()’

La función url() permite especificar una ruta válida, ya sea relativa o absoluta, de un archivo SVG. También se indicará el identificador (id) de un elemento de tipo geométrico que contiene el trayecto deseado, separándolo del nombre del archivo indicado mediante el símbolo de la almohadilla (#).

Este identificador que servirá para hacerle referencia puede encontrarse en uno de los siguientes elementos de tipo geométrico: <circle>, <ellipse>, <line>, <path>, <polygon>, <polyline> o <rect>.

Imaginemos que tenemos el archivo imagen.svg, y que dentro de este archivo hay un elemento <path> con el identificador id=trayecto. Si queremos usar este trayecto, indicaremos lo siguiente en el código CSS:

.ejemplo {
  offset-path: url("imagen.svg#trayecto");
}

Tal y como se puede observar, se ha indicado el nombre del archivo y el nombre del identificador, que en este caso es «trayecto».

Puede darse el caso de que el elemento geométrico esté en el mismo documento HTML, no en un archivo externo. Lo que haremos es indicar simplemente el identificador (id) seguido de la almohadilla. Así:

.ejemplo {
  offset-path: url("#trayecto");
}

En este caso, se ha indicado únicamente el nombre del identificador («trayecto») usando la almohadilla como prefijo.

Si como parámetro de la función url() no se hace referencia a un elemento de tipo geométrico o no es una ruta válida, se utilizará por defecto el valor path("M0,0"), que es un valor válido para formas geométricas.

Figuras geométricas

Más allá de las funciones ray() y url(), también puede usarse como valor de la propiedad offset-path cualquier función que permita generar figuras geométricas, sin tener que hacer referencia a un elemento con un id.

Lista de funciones para generar figuras geométricas:

Función Descripción
inset() Define un rectángulo interior.
circle() Define una figura circular.
ellipse() Define una figura elíptica.
polygon() Define una figura poligonal.
path() Define una figura a partir de un trayecto SVG.
rect() Define un rectángulo con distancias desde los bordes.
xywh() Define un rectángulo con desplazamiento y tamaño.

Veamos algunos ejemplos:

.ejemplo {
  offset-path: circle(25px at 0 50%);
}

.ejemplo {
  offset-path: path('m 0 0 h 150 v 100');
}

.ejemplo {
  offset-path: rect(0 10px 50px 60px round 10px);
}

.ejemplo {
  offset-path: rect(0 10px 50px 60px round 10px);
}

La propiedad ‘offset-position’

La propiedad offset-position permite definir la posición inicial del elemento en relación con el trayecto que debe recorrer. Dado que la posición depende del recorrido, esta propiedad se usa en combinación con offset-path.

El valor por defecto es normal, con el que se indica que el elemento no tiene una posición inicial desplazada. Lo que hace este valor es ubicar el elemento al 50% de los ejes horizontal y vertical, centrándolo en el elemento contenedor.

Esta propiedad admite entre uno y cuatro valores que pueden ser palabras clave de posición, valores numéricos de longitud, que pueden ser relativos o absolutos, o una mezcla de ambos. Funciona como la propiedad background-position.

Cuando se especifica un único valor, se refiere al eje horizontal, y por tanto se aplicará el valor por defecto en el eje vertical; quedará centrado (50%). Con dos valores que sean numéricos usando unidades de longitud, el primer valor representa la posición horizontal y el segundo representa la posición vertical.

Podría indicarse dos valores haciendo uso de las palabras clave de posición que se listan a continuación, junto con sus equivalencias en porcentaje:

Valor Equivalencia
top 0%
left 0%
center 50%
bottom 100%
right 100%

Finalmente, si se usa tres o cuatro valores, se utiliza las palabras clave de posición como top, bottom, right y left para usar estas zonas como referencia a partir de la que se separará según la longitud indicada. Por ejemplo, top 10px significa que se separa 10 píxeles desde arriba.

El valor auto lo que hace es indicar como posición inicial un desplazamiento hacia la esquina superior izquierda del elemento contenedor (padre). Este valor es equivalente a indicar top left o 0% 0%.

Veamos algunos ejemplos:

.ejemplo {
  offset-position: normal;
}

.ejemplo {
  offset-position: 20% 60%;
}

.ejemplo {
  offset-position: right bottom;
}

.ejemplo {
  offset-position: right 5px top 20px;
}

La propiedad ‘offset-distance’

La propiedad offset-distance permite especificar la distancia del recorrido que debe realizar el elemento. Debido a que la distancia depende del recorrido, debe existir un trayecto válido en la propiedad offset-path.

El valor de esta propiedad será numérico en unidades de longitud o mediante un porcentaje. Por ejemplo, si se indica un valor del 50%, el elemento recorrerá solamente la mitad del trayecto. Si se indica 50 píxeles, recorrerá justamente esta distancia. El valor por defecto es 0, con el que se queda quieto.

Veamos algunos ejemplos:

.ejemplo {
  offset-distance: 0;
}

.ejemplo {
  offset-distance: 80%;
}

.ejemplo {
  offset-distance: 100px;
}

La propiedad ‘offset-rotate’

La propiedad offset-rotate permite definir la orientación del elemento mientras esté recorriendo el trayecto definido con la propiedad offset-path. Imagina un elemento en forma de flecha que recorre un camino con curvas: será lógico que la flecha siempre se oriente siguiendo la ruta trazada.

El valor más importante y que ya funciona por defecto es auto, con el que el elemento recorrerá el trayecto rotando sobre si mismo —es decir, orientándose— en la medida que el trayecto vaya cambiando de dirección.

Si lo que queremos es que, además de orientarse de forma automática, lo haga partiendo de un ángulo distinto, se indica el ángulo después de auto. Por ejemplo, con auto 90deg estará rotado 90 grados y seguirá orientándose.

Por el contrario, se puede provocar que se oriente de forma automática hacia el lado opuesto sin tener que usar auto 180deg. Para lograr este efecto es tan simple como usar la palabra clave reverse. Son valores equivalentes.

Finalmente, también es posible indicar un valor numérico usando las unidades de ángulo, como los grados (deg), los grados centesimales (grad), los radianes (rad) y las vueltas (turn). En estos casos, el elemento tiene una rotación constante y fija, sin adaptarse a los cambios de dirección del trayecto.

Veamos algunos ejemplos:

.ejemplo {
  offset-rotate: auto;
}

.ejemplo {
  offset-rotate: reverse;
}

.ejemplo {
  offset-rotate: auto 45deg;
}

.ejemplo {
  offset-rotate: 25deg;
}

La propiedad ‘offset-anchor’

La propiedad offset-anchor permite especificar un punto de origen para el elemento que debe recorrer el trayecto definido. Este punto se ubica en la caja del elemento a desplazar. Por ejemplo, indicando la esquina inferior izquierda, quedará desde ese punto hacia arriba y hacia la derecha.

El funcionamiento de esta propiedad es muy similar al de offset-position, ya que admite de uno a cuatro valores, teniendo en cuenta que si se indica dos valores se refiere a los desplazamientos en horizontal (eje X) y en vertical (eje Y). Si estos dos valores son numéricos pueden ir precedidos de las palabras clave de posición (left, right, top y bottom). Con un solo valor se refiere al eje horizontal; entonces lo centra en el vertical. El valor por defecto es auto.

Veamos algunos ejemplos:

.ejemplo {
  offset-anchor: auto;
}

.ejemplo {
  offset-anchor: 30% 60%;
}

.ejemplo {
  offset-anchor: left top;
}

.ejemplo {
  offset-anchor: left 1em bottom 10px;
}

La propiedad ‘offset’

La propiedad offset es una abreviatura (shorthand) para definir trayectos y configurarlos con los parámetros de las propiedades CSS descritas en este artículo. Los valores se deben introducir siguiendo el orden que se especifica a continuación. Si falta algún valor, se usará el valor por defecto de forma automática.

La propiedad mask es una abreviatura (shorthand) que permite indicar de una forma sintetizada y resumida los atributos de las propiedades sobre máscaras descritas en este artículo. Los valores deben seguir un orden. En caso de faltar una propiedad, se usará automáticamente el valor por defecto.

  1. offset-position
  2. offset-path
  3. offset-distance
  4. offset-rotate
  5. offset-anchor

En el caso de offset-anchor, se introduce justo después de offset-rotate separándolos con una barra inclinada (/).

Por ejemplo:

.ejemplo {
  offset:
    top right
    ray(180deg contain)
    75%
    45deg / 30% 30%;
}
← Artículo anterior
Artículo siguiente →