Função de potência - CSS-Tricks

Anonim

Embora seja muito útil com aritmética, Sass fica um pouco aquém das funções de ajuda matemática. Houve um problema aberto no repositório oficial para solicitar mais funções relacionadas à matemática por quase 3 anos.

Alguns fornecedores terceirizados, como Compass ou SassyMath, fornecem suporte avançado para recursos matemáticos, mas são dependências externas que podem (devem?) Ser evitadas.

Um dos pedidos mais populares neste assunto é uma função de potência ou mesmo um operador expoente. Infelizmente, ainda não há suporte para isso no Sass e, embora ainda esteja em discussão ativa, é improvável que aconteça muito em breve.

Enquanto isso, ser capaz de elevar um número a uma certa potência é muito útil em CSS. Aqui estão alguns exemplos em que seria útil:

  • para determinar a luminância de uma cor;
  • para fixar um número a uma certa quantidade de dígitos;
  • fazer alguma trigonometria (inversa) ...

Implementação Sass

Felizmente para nós, é possível (e bastante simples) criar uma função de potência com nada além de Sass. Tudo o que precisamos é um loop e alguns operadores matemáticos básicos (como *e /).

Expoentes inteiros positivos

Nossa função (nomeada pow) em sua forma menor seria assim:

@function pow($number, $exponent) ( $value: 1; @if $exponent > 0 ( @for $i from 1 through $exponent ( $value: $value * $number; ) ) @return $value; )

Aqui está um exemplo:

.foo ( width: pow(20, 2) * 1px; // 400px )

Expoentes inteiros positivos ou negativos

No entanto, ele só funciona com um argumento positivo `$ power`. Permitir expoentes negativos não seria tão difícil, só precisamos de uma pequena condição extra:

@function pow($number, $exponent) ( $value: 1; @if $exponent > 0 ( @for $i from 1 through $exponent ( $value: $value * $number; ) ) @else if $exponent < 0 ( @for $i from 1 through -$exponent ( $value: $value / $number; ) ) @return $value; )

Aqui está um exemplo:

.foo ( width: pow(10, -2) * 1px; // 0.0001px )

Expoentes positivos ou negativos

Agora, e se quisermos expoentes não inteiros? Como 4.2por exemplo? A verdade é que realmente não é fácil. Ainda é possível, mas requer mais do que apenas um loop e algumas operações.

Isso foi feito no repositório Bourbon para completar a modular-scale(… )função do framework (embora tenha sido recusado). Aqui está o código:

@function pow($number, $exponent) ( @if (round($exponent) != $exponent) ( @return exp($exponent * ln($number)); ) $value: 1; @if $exponent > 0 ( @for $i from 1 through $exponent ( $value: $value * $number; ) ) @else if $exponent pow(10, $ten-exp)) ( $ten-exp: $ten-exp + 1; ) @return summation(ln-maclaurin, $value / pow(10, $ten-exp), 1, 100) + $ten-exp * $ln-ten; )

Outras considerações

Bem, isso foi intenso. Se acontecer de você precisar de suporte para expoentes não inteiros (como 4.2), recomendo que você use uma dependência externa que o forneça (como sass-math-pow) em vez de incluir todo esse código em seu projeto. Não que seja uma coisa ruim em si, mas não é realmente o papel do seu projeto hospedar um monte de código polyfilling não criado (é por isso que temos gerenciadores de pacotes).

Observe também que todas essas operações são bastante intensas para uma camada tão fina como Sass. Neste ponto, e se seu projeto depender de funções matemáticas avançadas, provavelmente é melhor passar a implementação desses auxiliares da camada superior (Node.js, Ruby, etc.) para Sass por meio de um sistema de plug-ins (Eyeglass, Ruby gema, etc.).

Mas para pow(… )uso básico , não posso recomendar as versões simples o suficiente!