Defining a Sass function directive is a lot like defining a function in most programming languages. First, we need the function keyword. Then we need a name, some parentheses, and it can accept arguments. Now, we need some brackets and a return statement.
We use function directives just like a built-in Sass function. Now, we got some mad background. However, Sass functions cannot affect anything outside of their scope. We can try to update a variable in the function, but the function won't update a variable defined outside of itself.
Sass functions are designed to return a value, so if there's no return statement, there will be an error. If there is no return value, same deal. Sass functions can have default arguments. Let's make a new class for the default argument.
They can also have optional arguments. We can use the if function to determine if an image was passed to the argument, so if there is an image, the background will have a URL, otherwise, it won't. Now, we just add the URL to the end of the return statement, and we need a class with an image.
That class didn't pass an image, and boom, there's a unicorn. If we use a named argument for the optional argument, the default argument is still included. There is the default color in the unicorn background.
Function directives can have variable arguments, too. Let's just add those extra values to the end of the return statement. Now, we just need a class with some more values. We have the magic class with a color, a URL, and some extra values.
We could have written this with a mixin. Why use a function directive when we can get the same end result with a mixin? Mixins return reusable blocks of styles. Functions return reusable values. Getting the background works for either depending on the use case.
Calculating typographic scale is definitely a job for a function directive. We can use typographic scale to determine font size for header elements. The function return statement will look something like base font size times a ratio to the nth power.
First, we need to calculate for ratio to the nth power, so we need a ratio. Our function will accept an exponent, which is just another name for the nth power. We need a variable that will be the accumulated value of looping nth times, where in each loop, it multiplies itself times the ratio.
We can use the debug directive to print out the value for each iteration, but our function won't work without a return statement, so let's add one of those. We need to call the function to see the debug in action.
We've looped six times. Again, the value will equal the final iteration value. We don't need that debug anymore. We can just multiply the value times a base font size.
If we pass a zero to the font scale function, it should return the base font size, but we're not getting the base font size because we're not compensating for zero. We're looping from one through the exponent.
One solution we could use is the if function in the return statement. If the exponent is greater than zero, return the base font size times the value. Otherwise, just return the base font size. Now, we're getting the base font size when we pass a zero to our font scale function.
This will also help us guard against negative exponents. If we use a negative number, we still get the base font size. The font scale function can be used on individual classes, or we can combine it with other Sass features, like looping for header elements.
We're going to need to loop six times for headers one through six, create the exponent for each loop, interpolate the loop number for each header, and pass the exponent to the font scale function. There's our header elements.
We can make the font scale function a reusable module by passing the font size and the ratio as arguments. We can even give them default values.
Notice all the font sizes are the same, because the base font and ratio values haven't changed. The user can still pass in their own base font size or ratio values.
Now the header font size is half-changed, because the font scale function is not using the default ratio.