How do you strip the unit from any number in SASS?
Asked Answered
W

3

54

I know you can strip units from numbers in SASS when you know the unit before-hand like this:

$number: 16px;
$without-unit: 16px / 1px;
@warn $without-unit; // 16

But is it possible to strip the unit from a number without knowing what the unit is first?

@function strip-unit($number) {
  // magic code here...
}

@warn strip-unit(16px); // 16
Warranty answered 8/9, 2012 at 5:23 Comment(2)
It amazes me that this isn't a core SASS functionEmission
You can use function from css-tricks.com/snippets/sass/strip-unit-functionBadenpowell
T
137

--

UPDATE: You should never actually need to use this function. Sass math is very smart about units, and I have never seen a use-case in which stripping units was a better option than simply using correct math to get what you need. See the Sass issue thread where this has been discussed at length.

It's a clever function, but if you ever feel like using it, there's probably a problem with your math. Don't fall back on this function. Fix your math instead.

--

You need to divide by 1 of the same unit. If you use unit(), you get a string instead of a number, but if you multiply by zero and add 1, you have what you need:

@function strip-units($number) {
  @return $number / ($number * 0 + 1);
}

UPDATE: In the latest versions of Sass, that becomes:

@use 'sass:math';

@function strip-units($number) {
  @return math.div($number, ($number * 0 + 1));
}

That works. strip-units(13.48cm) will return 13.48.

Terat answered 9/9, 2012 at 1:27 Comment(16)
Brilliant; this is way simpler than what I've been doing.Scarify
genious, once you understand it. simply genious!Cyprian
Note that this is not generally recommended. I have not yet ever found a good reason to strip units from numbers in Sass. I've run into many situations where it seemed like a good idea — but Sass is so smart about unit-math, leaving the units in place always gives the best/simplest results in the end.Terat
@EricMeyer if I use this code within my application (copied 1:1 from your example) I get this warning --> Syntax error: Undefined operation: "2.1875rem times 0" at the line-number of the @return statement... I'm using this function within another function because it seems that I'm not able to use SASS to add two rem units...Showboat
Sorry, I can't recreate either problem. The function works fine for me, as does adding rem units together. Sass math is very powerful and flexible with units. If you run into something like not being able to add two rem units, you shouldn't look for a workaround like mine, you should look for the source of the problem. Isolate the problem, file an issue on github, and have someone help you track it down.Terat
After updating to Foundation 5, I'm having to rework a fair amount of my SASS. I'm getting the same error that herom is getting. Is there a built-in function for Foundation 5 that will do this instead?Tui
This really isn't an issue you should be having, or working around. It certainly shouldn't have anything to do with Foundation. You should go file a bug with Sass, and get your actual problem fixed.Terat
It amazes me that SASS doesn't provide this function out of the box.Emission
You really really shouldn't ever use this function. It isn't provided in Sass because it isn't needed. I have never yet been shown a use-case where stripping units is better than letting Sass handle unit-math correctly.Terat
@EricMSuzanne, Here's a real world use case. I have a map of breakpoints (550px,1024px). Now I want to loop through that map and add a media query for each one. Easy. But I also want to add a class for each breakpoint, such as .show-from-$var-up. I would like that to parse to .show-from-550-up not .show-from-550px-up.Perrone
»never seen a use-case in which stripping units was a better option than simply using correct math« Then you do not know all use cases…Frankhouse
Fix my math? But this is much easier :(Skeptic
Use case: when an image url needs a lightness value without a %.Pronounce
The first part of this answer which is advising against using this function is unnecessary, and also inaccurate. There are numerous valid use-cases for this.Grizel
SassError: Undefined operation "0.9375rem * 0" font-size: math.div($-fs, $-fs * 0 + 1) * conf.$font-size-root;Massorete
Some of Sass's own built-in functions allow unitless values to be passed, even when the function expects a % unit. Examples are mix() and darken(). While this practice is debatable (and some functions now say unitless values are deprecated), is it unreasonable for someone to want to replicate Sass's behaviour with their own functions? Since they can't possibly know whether such an argument will include the unit, this seems like a valid use-case to me.Amara
X
0

I think you'd have to add a custom Ruby function to strip the units (see the documentation on adding custom functions). It would look something like this, I think (warning, untested):

module Sass::Script::Functions
  def strip_units(num)
    assert_type num, :Number
    Sass::Script::Number.new(num.value)
  end
end
Ximenes answered 8/9, 2012 at 22:12 Comment(0)
B
0

The only use case for strip units SASS function is when writing unit conversion functions. I've only found it useful for the task of converting PX to EM/REM and vice versa.

You need to divide by 1 of the same unit. If you use unit(), you get a string instead of a number, but if you multiply by zero and add 1, you have what you need - Miriam Suzanne

I believe SASS compiler treats values very similarly to what PHP interpreter does (with a warning though), so I believe the statement above is incorrect. If you divide or multiply a string (which starts with a number e.g. '16px') with a number value (or a string value that starts with a number), the string is converted to number for the compiler to be able to perform the operation.

Same goes for adding a string to number, it converts the number to a string.

The following solution applies this tactic correctly:

@function strip-unit($value) {
  @return $value / 1;
}
Buffum answered 12/2, 2021 at 11:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.