Funções trigonométricas no CSS

Calcule o seno, cosseno, tangente e muito mais no CSS.

Funções trigonométricas

No CSS, é possível escrever expressões matemáticas. Na base, há a função calc() para fazer cálculos, mas é provável que você também tenha ouvido falar de min(), max() e clamp().

Além dessas funções, há as funções trigonométricas sin(), cos(), tan(), asin(), acos(), atan() e atan2(). Essas funções são definidas no Módulo de unidades e valores do CSS nível 4 e estão disponíveis em todos os navegadores.

Compatibilidade com navegadores

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

Origem

sin(), cos() e tan()

As três funções trigonométricas principais são:

  • cos(): retorna o cosseno de um ângulo, que é um valor entre -1 e 1.
  • sin(): retorna o seno de um ângulo, que é um valor entre -1 e 1.
  • tan(): retorna a tangente de um ângulo, que é um valor entre −∞ e +∞.

Ao contrário das contrapartes do JavaScript, essas funções aceitam ângulos e radianos como argumento.

Na demonstração a seguir, essas funções são usadas para desenhar as linhas que compõem o triângulo que envolve o conjunto --angle:

  • A "hipotenusa" (linha amarela) é uma linha que vai do centro do círculo até a posição do ponto. O comprimento é igual ao --radius do círculo.
  • A linha vermelha "adjacente" é uma linha do centro do círculo ao longo do eixo X. O comprimento é igual a --radius multiplicado pelo cosseno de --angle.
  • O "oposto" (linha azul) é uma linha a partir do centro do ponto ao longo do eixo Y. O comprimento é igual a --radius multiplicado pelo seno de --angle.
  • A função tan() do --angle é usada para desenhar a linha verde do ponto em direção ao eixo X.

asin(), acos(), atan() e atan2()

As contrapartes arc ou inversas de sin(), cos() e tan() são asin(), acos() e atan(), respectivamente. Essas funções fazem o cálculo na direção oposta: elas usam um valor numérico como argumento e retornam o ângulo correspondente.

Por fim, há atan2(), que aceita dois argumentos A e B. A função retorna o ângulo entre o eixo X positivo e o ponto (B,A).

Exemplos

Há vários casos de uso para essas funções. Confira a seguir uma pequena seleção.

Mover itens em um caminho circular em torno de um ponto central

Na demonstração a seguir, os pontos giram em torno de um ponto central. Em vez de girar cada ponto em torno do próprio centro e depois movê-lo para fora, cada ponto é traduzido nos eixos X e Y. As distâncias nos eixos X e Y são determinadas considerando o cos() e, respectivamente, o sin() do --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 os pontos de maneira uniforme ao redor do ponto central, cada ponto recebe um deslocamento adicional com base no índice nth-child. Por exemplo, se houver três pontos, há uma distância de 120deg (= 360deg / 3) entre cada ponto.

  • O primeiro elemento filho de três é deslocado por 0 x 120deg = 0deg.
  • O segundo elemento filho de três é compensado por 1 x 120deg = 120deg.
  • O terceiro elemento filho de três é compensado por 2 x 120deg = 240deg.

Girar um elemento para que ele fique de frente à origem

A função atan2() calcula o ângulo relativo de um ponto para outro. A função aceita dois valores separados por vírgulas como parâmetros: a posição y e x do outro ponto, em relação ao ponto de origem que fica na origem 0,0.

Com o valor calculado, é possível girar elementos de modo que fiquem voltados uns para os outros usando as propriedades de transformação individual.

No exemplo abaixo, as caixas são giradas para ficarem de frente ao local do mouse. A posição do mouse é sincronizada com uma propriedade personalizada usando 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)
          );
}

Destaque da comunidade

Como demonstrado nesta faixa de Möbius animada da Ana Tudor, cos() e sin() podem ser usados para mais do que apenas traduções. Aqui, o resultado é usado para manipular os componentes s e l da função de cor hsl().