In a previous lesson, we learned how to use mixins as functions. Remember that functions are snippets of code that can take arguments and eventually return the result of their work. In this way, we can perform operations on different numbers. A simple example is to find the square of any number. To do this, we need to multiply a number by itself. Let's try to do this using SASS.
To create a function in SASS, we use the keyword `@function' followed by the unique function name.
It is the name we will refer to it by later:
@function square
Now we have to define the arguments of our function. Arguments are variables on which the function result depends.
If you're familiar with mixins, you won't have any problems here. Unlike mixins, any function has parentheses after its name, even if we pass no arguments.
Our squaring function takes one argument, the number that is squared. Don't forget that argument names can be arbitrary and are necessarily specified as variables:
@function square($number) {
}
Now it's our turn to write the body of the function, which contains all the necessary calculations:
@function square($number) {
$result: $number * $number;
}
What happened here? We created a variable $result
in which we put the result of multiplying a number by itself. Creating a resulting variable is good practice to help you figure out your code faster.
When choosing variable names, make sure that they are meaningful. It makes no sense to create variables named $abc
or $lala
. Yes, it's a shortcut. But you will not remember what you store in a particular variable after a week. You can read about naming in programming in our blog.
Any function always returns something. But in our case, it only counts but returns nothing. It's like hearing a question, finding the answer, and not telling anyone.
For the function to be able to tell what it has calculated, we use the @return
construct. It is followed by what we want to return. In this case, the variable $result
:
@function square($number) {
$result: $number * $number;
@return $result;
}
Now our function is ready. It has a name and arguments, does operations inside itself, and returns some results. It is easy enough to see that. Let's try to call our function. To do this, all we have to do is specify its name and the arguments it takes:
$side: 10;
@function square($number) {
$result: $number * $number;
@return $result;
}
.square {
width: #{square($side)}px;
height: #{square($side)}px;
}
Compile our file and get the following CSS code:
.square {
width: 100px;
height: 100px;
}
The example may seem rather useless now, but over time you will learn about the various constructs that are possible to use in the body of your functions. It is a powerful tool that will save you dozens of hours in development.
How to return values
In the last example, we returned the result using the @return
construct and the $result
variable created at the beginning of our function body. With such simple calculations, you may not use an additional variable but substitute the necessary expression directly in @return
. It will reduce the amount of code.
But be careful — only use expressions in @return
if you fully understand the structure of the expected result. Never chase to write the shortest possible functions. They may be difficult to maintain later on.
For simple multiplication, you can use @return
all at once. Then our function will look like this:
@function square($number) {
@return $number * $number;
}
How to return another functions
Besides getting a value, we can return other functions.
In this case, the code executes the returned function first and returns its value. It is convenient in large projects when the first function counts arguments for the second one and calls it.
This way, we can write short functions that are easy to read and understand.
Let's pretend we want to square the sum of the passed arguments.
We should take all arguments modulo so that there are no negative values. If we already had a squared function before, there is no point in reintroducing it in a new one. You can use it when returning a value. And to take the modulus, we will use the built-in function abs()
:
@function square($number) {
@return $number * $number;
}
@function abs-square-sum($number-one, $number-two) {
$number-one: abs($number-one);
$number-two: abs($number-two);
$sum: $number-one + $number-two;
@return square($sum);
}
@debug abs-square-sum(-10, 5);
The result of abs-square-sum(-10, 5)
is 225
.
Functions or mixins?
At first glance, there is not much difference between mixins and functions. Then why do we need this division? We use mixins everywhere and live in peace. We use the same syntax and don't get confused anymore.
It is necessary to distinguish for yourself whether to use functions or mixins. Mixins are, first and foremost, the ability to reuse CSS properties. You should not try to use more logic there than necessary. Functions are used for calculations and are often not directly related to CSS.
Consider this statement using the example of increasing the font size by one and a half times. When using mixins, it might look like this:
$font-size: 16;
@mixin big-text($size) {
font-size: #{$size * 1.5}px;
}
.main {
.error {
@include big-text($font-size);
}
}
After compilation, we get the following code:
.main .error {
font-size: 24px;
}
Let's perform the same transformations but using functions:
$font-size: 16;
@function multiply-by-one-and-half($number) {
@return $number * 1.5;
}
.main {
.error {
font-size: #{multiply-by-one-and-half($font-size)}px;
}
}
The result of this function will be the same. We will refrain from copying it :) As you can see, we got the same results with two different approaches. The main point of the functions is that we don't care where we do the multiplication by one and a half. Also, we can use this function to calculate indentation, height/width. We do not have any property or unit constraints.
It is the place where functions have the edge over mixins. Always consider the purpose of the computation. Depending on that, choose either mixins or functions.
Are there any more questions? Ask them in the Discussion section.
The Hexlet support team or other students will answer you.
For full access to the course you need a professional subscription.
A professional subscription will give you full access to all Hexlet courses, projects and lifetime access to the theory of lessons learned. You can cancel your subscription at any time.