I’ve been refactoring my CSS to a SASS style sheet recently. I’m using the Mindscape Web Workbench extension for VS2012, which re-generates the CSS each time you save your SCSS. I started with code similar to this:
/* Starting point: */
h1 { font-size: 1.5em; /* 24px ÷ 16px */ }
Then I tried to refactor it first to this:
/* Recfator: */
h1 { font-size: (24px / 16px)em; }
But this unfortunately produces:
/* Result: */
h1 { font-size: 1.5 em; } /* doesn't work, gives "1.5 em" */
Notice the extra space, which I don’t want there. I’ve tried several alternatives, here are a few:
h1 { font-size: (24/16)em; } /* doesn't work, gives "1.5 em" */
h2 { font-size: 24 / 16em; } /* doesn't work, gives "24/16em" */
h3 { font-size: (24px / 16px) * 1em; } /* works but "* 1 em" feels unnecessary */
h4 { font-size: (24em) / 16; } /* works, but without "px" it's not
really conveying what I mean to say */
I’ve also tried these variants with variables (because I want those anyways), but that didn’t change the situation much. To keep the examples in this question sleek I’ve left out variables. However, I’d happily accept a solution that relies on using variables (in a clean way).
I’ve gone through the relevant SASS documenation on ‘/’, and appreciate that this is a tough one for SASS because the ‘/’ character already has a meaning in basic CSS. Either way, I was hoping for a clean solution. Am I missing something here?
PS. This blogpost does offer one solution, using a user defined function. That seems a bit heavy-weight though, so I’m interested if there’s “cleaner” solutions in line with my attempts above. If someone can explain the “function approach” is the better (or even only) solution then I’ll accept that as an answer too.
PS. This related question seems to be about the same thing, though that one specically wants to do further calculations. The accepted answer there is my third workaround (multiplying by 1em), but I’d love to know if there’s a different (cleaner) way if I’m willing to forego the ability to do further calculations. Perhaps the method mentioned in said question (“interpolation”) is useful for me?
Bottom line: how can you cleanly append the unit type (e.g. em) to the result of a calculation in SASS?
The only way to add a unit to a number is via arithmetic.
To perform operations like concatenation (eg.
1 + px) or interpolation (eg.#{1}px) will only create a string that looks like a number. Even if you’re absolutely 100% certain that you’re never going to use your value in another arithmetic operation, you should not do this.More important than not being able to perform arithmetic operations, you won’t be able to use them with other functions that expects a number:
There is nothing to be gained by casting your numbers to strings. Always use arithmetic (multiplication by 1, or addition by 0) to add a unit:
Output:
Here’s a mixin I wrote as part of my Flexbox mixin library that will choke if you pass in a string (for those not familiar with Flexbox, the original specification only allows integers for the
box-flexproperty.flex: autoorflex: 30emcannot be made compatible with the comparablebox-flexproperty, so the mixin doesn’t bother trying)