Is it possible to add a (dynamic) unit to a unitless number in sass?

这一生的挚爱 提交于 2019-12-07 18:12:15

问题


First of all, I am aware that to turn a unitless value into one with a unit I can multiply a unitless value by a single unit:

$value: 25 * 1px; // 25px

However I would like to know if there is any way to do this when the unit is dynamic.

$unit: rem;
$value: 23;

.Box {
  // Try interpolation
  $united-value: #{$value}#{$unit};
  value: $united-value; // Appears to be correct
  // Check it is actually a number using unitless 
  check: unitless($united-value); // $number: "23rem" is not a number for `unitless'
}

Obviously if I was to make the value of $unit 1rem I could just multiply as in my first example, but is there a way to do this with a naked unit value.

Sassmeister here

[Edit] As @zessx correctly states, CSS doesn't care about the type and will treat both string and number values identically in this case. However I need to perform operations on the value once the unit has been appended.

[Edit] I'm not sure how I can be any clearer. I don't want / need a function that uses multiplication under the hood. I already know how that works and how to do it. I am interested if there is a way to take a unitless value and a unit and make a united number out of it.

Is there a a way to take px and 22 and make 22px that is a number and can have mathematical operations performed on it? Any answer that shows me how I can take 1px and 22 and do the same thing is not answering the question I'm asking.


回答1:


There's no sass native way to achieve your goals. The problem is that $unit is a string and in sass, like other languages, when you make operations with a string and a number, it automatically concatenates both and returns a string. And there is no native function that performs this operation, here's the reason of the creator of sass:

these functions would encourage more sloppy code than they do add expressive power.

More info about this topic here

Alternatives

So you can only use multiplication, as you've mentioned before or if you don't want to use multiplication you can use this function to convert unit strings into numbers:

@function length($number, $unit) {
  $strings: 'px' 'cm' 'mm' '%' 'ch' 'pica' 'in' 'em' 'rem' 'pt' 'pc' 'ex' 'vw' 'vh' 'vmin' 'vmax';
  $units:   1px  1cm  1mm  1%  1ch  1pica  1in  1em  1rem  1pt  1pc  1ex  1vw  1vh  1vmin  1vmax;
  $index: index($strings, $unit);

  @if not $index {
    @warn "Unknown unit `#{$unit}`.";
    @return false;
  }

  @return $number * nth($units, $index);
}

As you can see, it takes a number and a unit as arguments and it returns them as a length number. So in your case, you only need to change this declaration:

$united-value: #{$value}#{$unit};

By this other:

$united-value: lenght($value, $unit);

This is an idea grabbed from Hugo Giraudel's blog




回答2:


Even if $united-value looks like a united number, it's no more than a string, as Sass can't differentiate "rem" string from "rem" unit. Luckily, this string will be interpreted by any CSS engine.

You can check it with type-of() :

$unit: rem;
$value: 23;

.Box {
  $united-value: #{$value}#{$unit};
  value: $united-value;
  check: type-of($united-value); // check: string;
}

AFAIK, the only way to cast a string as "rem" is effectively to use * 1 rem.

EDIT:
As mentioned by Alex Guerrero, Hugo Giraudel built a function to cast a string into a number, you should really have a look on it blog. The good thing with it is that you can simply write this :

$unit: rem;
$value: 23;

.Box {
  $united-value: number($value+$unit);
  value: $united-value; 
  check: unitless($united-value);
}


来源:https://stackoverflow.com/questions/26356899/is-it-possible-to-add-a-dynamic-unit-to-a-unitless-number-in-sass

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!