Funciones trigonométricas en CSS

Calcula el seno, el coseno, la tangente y mucho más en CSS.

En CSS, es posible escribir expresiones matemáticas. En la base, se encuentra la función calc() para realizar cálculos, pero lo más probable es que también hayas oído hablar de min(), max() y clamp().

A estas funciones se unen las funciones trigonométricas sin(), cos(), tan(), asin(), acos(), atan() y atan2(). Estas funciones se definen en el módulo de valores y unidades de CSS nivel 4 y están disponibles en todos los navegadores.

Navegadores compatibles

  • Chrome: 111.
  • Edge: 111.
  • Firefox: 108.
  • Safari: 15.4.

Origen

sin(), cos() y tan()

Las tres funciones trigonométricas principales son las siguientes:

  • cos(): Muestra el coseno de un ángulo, que es un valor entre -1 y 1.
  • sin(): Muestra el seno de un ángulo, que es un valor entre -1 y 1.
  • tan(): Muestra la tangente de un ángulo, que es un valor entre −∞ y +∞.

A diferencia de sus contrapartes de JavaScript, estas funciones aceptan ángulos y radianes como argumento.

En la siguiente demostración, estas funciones se usan para dibujar las líneas que forman el triángulo que rodea el conjunto --angle:

  • La “hipotenusa” (línea amarilla) es una línea que va desde el centro del círculo hasta la posición del punto. Su longitud es igual a la --radius del círculo.
  • La "adyacente" (línea roja) es una línea desde el centro del círculo a lo largo del eje X. Su longitud es igual a --radius multiplicado por el coseno de --angle.
  • El “opuesto” (línea azul) es una línea desde el centro del punto a lo largo del eje Y. Su longitud es igual a --radius multiplicada por el seno de --angle.
  • La función tan() de --angle se usa para dibujar la línea verde del punto hacia el eje X.

asin(), acos(), atan() y atan2()

Los equivalentes arc o inversos de sin(), cos() y tan() son asin(), acos() y atan(), respectivamente. Estas funciones realizan el cálculo en la dirección opuesta: toman un valor numérico como argumento y muestran el ángulo correspondiente.

Por último, está atan2(), que acepta dos argumentos: A y B. La función muestra el ángulo entre el eje X positivo y el punto (B,A).

Ejemplos

Existen varios casos de uso para estas funciones. A continuación, se muestra una pequeña selección.

Cómo mover elementos en una ruta circular alrededor de un punto central

En la siguiente demostración, los puntos giran alrededor de un punto central. En lugar de rotar cada punto alrededor de su propio centro y, luego, moverlo hacia afuera, cada punto se traduce en los ejes X e Y. Las distancias en los ejes X e Y se determinan teniendo en cuenta cos() y, respectivamente, sin() de --angle.

:root {
  --radius: 20vmin;
}

.dot {
  --angle: 30deg;
  translate: /* Translation on X-axis */
             calc(cos(var(--angle)) * var(--radius))

             /* Translation on Y-axis */
             calc(sin(var(--angle)) * var(--radius) * -1)
  ;
}

Para distribuir los puntos de manera uniforme alrededor del punto central, cada punto recibe un desplazamiento adicional según su índice nth-child. Por ejemplo, si hay tres puntos, hay una distancia de 120deg (= 360deg / 3) entre cada uno.

  • El primer elemento secundario de tres se desplaza en 0 x 120deg = 0deg.
  • El segundo elemento secundario de tres se desplaza por 1 x 120deg = 120deg.
  • El tercer elemento secundario de tres se desplaza por 2 x 120deg = 240deg.

Rota un elemento para que se oriente a su origen

La función atan2() calcula el ángulo relativo de un punto a otro. La función acepta dos valores separados por comas como parámetros: la posición y y x del otro punto, en relación con el punto de origen que se encuentra en el origen 0,0.

Con el valor calculado, es posible rotar los elementos para que estén frente a frente, mediante las Propiedades de transformación individuales.

En el siguiente ejemplo, los cuadros se rotan para que apunten a la ubicación del mouse. La posición del mouse se sincroniza con una propiedad personalizada a través de JavaScript.

div.box {
  --my-x: 200;
  --my-y: 300;

  /* Position the box inside its parent */
  position: absolute;
  width: 50px;
  aspect-ratio: 1;
  translate: calc((var(--my-x) * 1px)) calc(var(--my-y) * 1px);

  /* Rotate so that the box faces the mouse position */
  /* For this, take the box its own position and size (25 = half the width) into account */
  rotate: atan2(
            calc((var(--mouse-x) - var(--my-x) - 25) * 1),
            calc((var(--mouse-y) - var(--my-y) - 25) * -1)
          );
}

Lo destacado de la comunidad

Como se muestra en esta cinta de Möbius animada de Ana Tudor, cos() y sin() se pueden usar para mucho más que solo traducciones. Aquí, su resultado se usa para manipular los componentes s y l de la función de color hsl().