Some of the best known features of Sass are the availability of mixins, variables, and the ability to extend selectors. However, what you might not know is that you can also define functions for use in your rulesets.
What is a Sass Function?
If you've used any of Sass's Operations, then you've used a function. Alternately, if you've used Compass or Bourbon, you've probably used a function. They look like this:
p { # Pure Sass background-color: transparentize($coolBlue, 0.25); # Compass margin: 0 auto rhythm(3, 42px); # Bourbon font-size: em(16, 14); }
Why do I care?
While it's not uncommon to see mixins get used for this purpose, they're often undesirably verbose or rigid. More importantly, using mixins alone encourages some bad behavior, making monolithically large functions that do too many things. In practice, it's better to have small discrete functions that just do one thing, but do it very well.
My most common use case is similar to what you see in the Bourbon example above, that of converting a pixel-based font size to a relative font size (em
or rem
).
Defining a function
The syntax for defining a function is similar to what's used to define a mixin:
@function myFunction($var: default) { // function logic ... @return $someValue; }
To create a rem
function like the em
one that is shown above, we'll actually need to define two functions, one for the actual conversion of pixels to rem
s, and another to strip the units off of a number. Why do we need to strip the units? Because, due to the way that Sass's math functions accommodate the presence of units, if we leave them there we won't get the value that we desire.
First we'll define strip-units
:
@function strip-units($number) { @return $number / ($number * 0 + 1); }
Then the rem
function:
@function rem($pxl, $base: 16) { @if not unitless($pxl) { $pxl: strip-units($pxl); } @if not unitless($base) { $base: strip-units($base); } @return ($pxl / $base) * 1rem; }
Note that we’re using yet another function, unitless
, which is provided by Sass (read the docs). Though you don't need to have that check (the strip-units
will work even on numbers that don't have units), it's good to not do more computation than necessary.
Once this is added to your Sass environment, you can call it at any point by simply writing your rule:
font-size: rem(24); // This will be output as "font-size: 1.5rem;", // since it will take 24 and divide that by the // default value of 16 that we set in the function
Functions, Functions, Everywhere
With functions, our Sass files can be even more efficient, the amount of code generated can be reduced, and maintaining these files is even easier. When trying to decide if you should write a mixin or a function, the easiest barometer is this, functions should return a value of some sort, mixins should return rules.
You can read more about the @function
directive in the Sass documentation.
Got any questions? Let us know! Also, for more DIY tips + tricks, check these out:
- How to Refresh an iOS Hybrid App
- Get Clearer Code with Underscore.js Chaining Syntax
- Using Storable and Faker to Create Mock Collections