2

In a LESS mixin, I have an alpha value that I'd like to convert to a plain number (0.xx) even if it is given as a percentage (xx%). I've found the percentage() function to convert a number to a percentage, but percentage(xx%) returns "xx00%" and dividing by 100 makes 0.xx into 0.00xx, which is no good either. All the "if-then" statements that I could find in LESS invlove making a new scope, so while I could detect the "%", I couldn't pass that information back into a variable to use it.

How do I go about converting a percentage to a number if and only if it is a percentage?

Harry
  • 87,580
  • 25
  • 202
  • 214
SuperFLEB
  • 204
  • 2
  • 11

3 Answers3

3

While you can use JS within Less to achieve the desired effect, a better approach would be to use the built-in ispercentage() and isnumber() type functions to check whether a variable value is a number or a percentage or neither and then output the value accordingly.

.percentlike(@var) {
  & when (ispercentage(@var)){ /* is input value a percentage */
    alpha: unit(@var / 100); /* unit() strips the % symbol */
    /* you could also use the replace function like below
      @percentage: @var / 100;
      alpha: replace(~"@{percentage}", "%", "");
    */
  }
  & when not (ispercentage(@var)) and (isnumber(@var)){ /* not percentage but is a number */
    alpha: @var;
  }
  & when not (ispercentage(@var)) and not (isnumber(@var)){ /* neither */
    alpha: ~"NaN";
  }
}

div#div1 {
  .percentlike(20%);
}
div#div2{
  .percentlike(0.2);
}    
div#div3{
  .percentlike(a);
}

Compiled CSS:

div#div1 {
  alpha: 0.2;
}
div#div2 {
  alpha: 0.2;
}
div#div3 {
  alpha: NaN;
}
Harry
  • 87,580
  • 25
  • 202
  • 214
  • Yeah, I get the impression this is the more "LESS-y" way to do it. My biggest issue with that was that there was another mess of guards that depended on another value, so it would have ballooned exponentially. – SuperFLEB Feb 24 '15 at 16:50
  • @SuperFLEB: Oh I see. Anyways no worries mate, it would atleast help future readers who may have similar needs. Your question was well written and an interesting one so I thought it deserved a pure Less answer :) – Harry Feb 24 '15 at 17:07
  • 1
    Btw. using `unit()` to convert `*%` to `*` is not a hack. This is actually the right way. – seven-phases-max Feb 24 '15 at 18:23
0

Try this: replace(~"@{value}", '%', '');

rtf_leg
  • 1,789
  • 1
  • 15
  • 27
  • Wouldn't that give me, for instance "20" instead "0.2" for "20%"? – SuperFLEB Feb 23 '15 at 23:25
  • Not, this expression just takes string representation of "value" variable and replace '%' char to nothing (i.e. just remove '%', nothing more). – rtf_leg Feb 23 '15 at 23:28
  • Okay, I'm looking for something to make it so both "20%" and "0.2" passed into the mixin can be converted to the same value of 0.2. – SuperFLEB Feb 23 '15 at 23:33
0

Well, it's an end-run, but I found a solution. You can use backticks to run arbitrary JS in LESS, so I just did...

.percentlike(@var1, @var2) {
  -percent-property: ~`"@{var1}".match(/%$/) ? parseFloat("@{var1}") / 100 : parseFloat("@{var1}")`;
  -decimal-property: ~`"@{var2}".match(/%$/) ? parseFloat("@{var2}") / 100 : parseFloat("@{var2}")`;
}

div {
  .percentlike(20%, 0.2);
}

Which, as desired, yields...

div {
  -percent-property: 0.2;
  -decimal-property: 0.2;
}
SuperFLEB
  • 204
  • 2
  • 11