Sass Basics: The Function Directive
I recently wrote an article about the basics of Sass, specifically the @mixin directive. In keeping with the theme of highlighting the basics of Sass, this time I will be talking about the @function directive.
What a function does
@function remy($pxsize) {
@return ($pxsize/16)+rem;
}
h1 { font-size: remy(32);}
A function looks a lot like a mixin, and they both accept the same types of arguments. Although they look similar,a Sass function behaves differently. While a mixin makes our life easier by lessening typing repetitive code, a function allows you to strip repeatable logic from your code. For example, in the code above we are using a function to calculate a rem value for a given pixel size. The resulting code would be:
h1 { font-size: 2rem; }
As you can see instead of applying styles to an element like you would with a mixin, all a function does is return a value for use in your stylesheets.
Function or a Mixin
The key to understanding when to use a function versus a mixin is knowing what you want. A mixin is used to create styles that would be a chore to continually write. Using a mixin you could easily write these styles with one line of code. When writing mixins you will be tempted to include calculations. We could have wrote the remy function as a mixin:
@mixin remy ($pxsize) {
font-size: ($pxsize/16)+rem;
}
h1 { @include remy(32);}
This would work but it is counter productive. First of all the mixin is locked into just calculating rem for font-size. What if we wanted to use our mixin for other properties? We could rewrite the mixin to take different arguments but that would be overkill.
A function on the other hand is designed to return a value. When you need to generate styles, use a mixin. When you need to encapsulate some logic, especially if you intend to use it across different elements in your project, then use a function. We can use our remy function across any element we choose.
h1 { font-size: remy(32);}
div { width: remy(800);}
How to create a function
To start, you create a Sass function by using the @function directive. This is followed by the name of the function and any arguments enclosed in parentheses.
$col-count: 12;
@function col-pct($columns) {
@return unquote((100/$col-count)*$columns+"%");
}
Remember a function only returns a value so we have to call @return to set the value returned by the function. Also note that the function can use any globally defined variables. The col-pct function above calculates the size in percentages of the specified number of columns. I am also using a built in Sass function, unquote to strip the quotes from the return value. Sass comes with a load of built in functions you can take a look at here.
How to use a function
A function is called by supplying the function name and any arguments. For example, to use the col-pct function to calculate the size of six columns:
.col-6 { width: col-pct(6);}
The resulting code is:
.col-6 { width: 50%; }
Arguments
We already saw that the function can use global variables. We can also use the same type of arguments we use with mixins. Of course we have to provide the arguments in the correct order. Lets say we modified the remy mixin to accept an argument for the rembase size.
@function remy($pxsize,$rembase) {
@return ($pxsize/$rembase)+rem;
}
If we supply the arguments in the wrong order we will get an incorrect value. Unless of course we use keyword arguments
Keywords
We can call the new remy function with the arguments in any order if we use keywords.
h3 { font-size: remy2($rembase:8,$pxsize:32 );
This will work correctly since we used keyword arguments.
Default Values
We can also use default values with our functions. A way to improve the rem function further would be to include a default value. That way specifying the rem base value will be optional.
@function remy($pxsize,$rembase:16) {
@return ($pxsize/$rembase)+rem;
}
We can then call the function one of two ways.
h3 { font-size: remy(32);}
p { font-size: remy(16,8);}
Both of these examples will work, although the rem base they are working from will be different.
Variable arguments
We can also use variable arguments in a function. The padding mixin from my @mixin article can be written as a function.
@function pad($pads...) {
@return $pads;
}
To use the function:
.five {padding: pad(25px,35px);}
.six {padding: pad(25px,35px,45px);}
.seven {padding: pad(25px,35px,45px,55px);}
Although functions are limited in their ability, I am sure you will be able to find some way to incorporate them into your projects. Try to strip out any logic for use across your projects in functions. If you come up with something useful it could come in handy in future projects.