53

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
cimmanon
  • 67,211
  • 17
  • 165
  • 171
jordanbtucker
  • 5,768
  • 2
  • 30
  • 43

3 Answers3

132

--

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.

Miriam Suzanne
  • 13,632
  • 2
  • 38
  • 43
  • Brilliant; this is way simpler than what I've been doing. – Paul d'Aoust Jan 08 '13 at 00:33
  • genious, once you understand it. simply genious! – Lajos Mészáros Jun 12 '13 at 13:14
  • 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. – Miriam Suzanne Oct 01 '13 at 21:58
  • 4
    @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... – herom Nov 18 '13 at 10:30
  • 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. – Miriam Suzanne Nov 18 '13 at 21:50
  • 1
    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? – Christopher Raymond Mar 10 '14 at 23:38
  • 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. – Miriam Suzanne Mar 11 '14 at 02:54
  • 2
    It amazes me that SASS doesn't provide this function out of the box. – Már Örlygsson Jul 06 '14 at 11:38
  • 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. – Miriam Suzanne Jul 09 '14 at 16:24
  • 2
    @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`. – JakeParis Feb 17 '15 at 17:07
  • 7
    »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… – feeela Jul 24 '15 at 15:24
  • Fix my math? But this is much easier :( – pilau Aug 02 '15 at 13:23
  • 2
    Use case: when an image url needs a lightness value without a `%`. – Jason Sep 08 '16 at 06:23
  • 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. – Arad Alvand Oct 05 '21 at 08:19
  • 1
    `SassError: Undefined operation "0.9375rem * 0"` `font-size: math.div($-fs, $-fs * 0 + 1) * conf.$font-size-root;` – north.inhale Feb 04 '22 at 07:42
  • 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. – Kal Mar 15 '22 at 21:35
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
hopper
  • 13,060
  • 7
  • 49
  • 53
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;
}
stamat
  • 1,832
  • 21
  • 26