Strömfunktion - CSS-tricks

Anonim

Även om det är mycket användbart med aritmetik, faller Sass lite kort med matematiska hjälpfunktioner. Det har funnits en öppen fråga i det officiella arkivet för att be om mer matematikrelaterade funktioner i nästan tre år.

Vissa tredjepartsleverantörer som Compass eller SassyMath ger avancerat stöd för matematiska funktioner, men de är externa beroenden som kan (bör?) Undvikas.

En av de mest populära förfrågningarna i denna fråga är en kraftfunktion eller till och med en exponentoperatör. Tyvärr finns det fortfarande inget stöd för detta i Sass och medan det fortfarande diskuteras aktivt är det osannolikt att det kommer att ske mycket snart.

Under tiden är det mycket användbart att kunna höja ett tal till en viss makt i CSS. Här är några exempel där det skulle vara till nytta:

  • för att bestämma luminansen hos en färg;
  • att fixa ett nummer till en viss mängd siffror;
  • att göra lite (invers) trigonometri ...

Sass implementering

Lyckligtvis för oss är det möjligt (och ganska enkelt) att skapa en kraftfunktion med inget annat än Sass. Allt vi behöver är en slinga och några grundläggande matematiska operatorer (som *och /).

Positiva heltalsexponenter

Vår funktion (namngiven pow) i sin minsta form skulle se ut så här:

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

Här är ett exempel:

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

Positiva eller negativa heltalsexponenter

Men det fungerar bara med ett positivt argument för "$ power". Att tillåta negativa exponenter skulle inte vara så svårt, vi behöver bara ett litet extra villkor:

@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; )

Här är ett exempel:

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

Positiva eller negativa exponenter

Tänk nu om vi vill ha icke-heltal exponenter? Såsom 4.2till exempel? Sanningen är att det verkligen inte är lätt. Det är fortfarande genomförbart, men det kräver mer än bara en slinga och några operationer.

Detta har gjorts i Bourbon-förvaret för att slutföra modular-scale(… )funktionen från ramverket (men har avvisats). Här är koden:

@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; )

Ytterligare överväganden

Det var intensivt. Om du råkar behöva stöd för icke-heltal exponenter (som 4.2), rekommenderar jag att du använder ett externt beroende som tillhandahåller det (till exempel sass-math-pow) istället för att inkludera all denna kod i ditt projekt. Inte för att det i sig är en dålig sak, men det är egentligen inte ditt projekts roll att vara värd för en så stor monter av icke-författad polyfilling-kod (det är därför vi har pakethanterare).

Observera också att alla dessa operationer är ganska intensiva för ett så tunt lager som Sass. Vid den här tiden, och om din design är beroende av avancerade matematiska funktioner, är det förmodligen bättre att skicka implementeringen av dessa hjälpare från det övre lagret (Node.js, Ruby, etc.) ner till Sass genom ett pluginsystem (Eyeglass, Ruby pärla, etc.).

Men för grundläggande pow(… )användning kan jag inte rekommendera de enkla versionerna nog!