Sass/SCSS Mixins, Functions & @includes Tutorial

In this Sass/SCSS tutorial we learn how to group sections of code and reuse them throughout our entire project with mixins and functions.

We cover how to define mixins & functions, how to @include mixins and invoke functions and how to add parameters and default fallback parameters.

Lastly we cover the differences between functions and mixins and when to use which.

What is a mixin

A mixin is one or more styles grouped together, allowing us to reuse them multiple times throughout our stylesheet without rewriting the code each time.

As an example, let’s consider a simple list reset.

Example:
margin: 0;
padding: 0;
list-style: none;

Instead of manually typing this section of code each time we want to reset a list, we throw it into a mixin and then use the mixin each time we need the reset.

note Mixins are typically only used for reusable styles and to modify variables. For more advanced functionality we use functions .

How to define a mixin

We define a mixin with the @mixin rule, followed by an identifier (name) and a code block.

Syntax: SCSS
@mixin identifier {
  // reusable code here
}

For example, let’s create a mixin for the list reset code earlier in the lesson.

Example: SCSS
@mixin list-reset {
  margin: 0;
  padding: 0;
  list-style: none;
}

How to use (include) a mixin

To actually use the mixin in our code, we have to include it where we want the style properties to be. To do that we use the @include rule, followed by the name of the mixin.

Syntax: @include
selector {
  @include identifier;
}

For example, let’s include the “list-reset” mixin we made earlier into the style of an unordered list.

Example:
ul {
  @include list-reset;
}

When we check the compiled CSS output, we can see that the contents of the mixin has been copied into the ul selector.

Output: Compiled CSS
ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

note Mixins aren’t globally available automatically. If your mixins live in separate files, they will need to be imported with @use into the document you want to use them in.

Including mixins within mixins

It’s possible for us to include a mixin within the definition of another mixin.

Example: SCSS
@mixin list-reset {
  margin: 0;
  padding: 0;
  list-style: none;
}

@mixin list-x {
  @include list-reset;

  li {
    display: inline-block;
    margin: 0 2rem 0 -2px;
  }
}

ul {
  @include list-x;
}

In the example above we include our basic “list-reset” into another mixin, called “list-x”, where we add more styling.

What will happen is that the compiler will first copy the “list-reset” contents into the “list-x” mixin. From there it will copy everything inside the “list-x” mixin, which now contains the “list-reset” mixin contents, into the ul selector.

Output: Compiled CSS
ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

ul li {
  display: inline-block;
  margin: 0 2rem 0 -2px;
}

Mixins with parameters

Parameters allow us to pass values to a mixin when it’s included, and have those parameter values influence our properties.

Parameters are Sass variables, written inside a pair of open and close parentheses, after the mixin name.

Example: SCSS
@mixin identifier($param_1, $param_2, ...) {

}

We can then use these parameters inside the code block of the mixin by simply referring to the variable name.

Example: SCSS
@mixin identifier($param_1, $param_2, ...) {
  property: $param_1;
  property: $param_2;
}

What will happen is that whatever we pass to the parameter in the parentheses when the mixin is included, will be copied into the code block where we reference that parameter.

Let’s see an example of a mixin that creates a solid border. The two parameters are the width and color that we want to be able to change each time we use the mixin.

Example: SCSS
@mixin border-solid($width, $color) {
  border: $width solid $color;
}

When we include the mixin now, we will have to pass values, otherwise known as arguments, to the parameter list.

Example: SCSS
@mixin border-solid($width, $color) {
  border: $width solid $color;
}

nav {
  @include border-solid(2px, #000);
}

In the example above, it will replace $width in the border property with 2px and $color with #000 .

Output: Compiled CSS
nav {
  border: 2px solid #000;
}

Default parameter values

We can define fallback, or default, values for our parameters. When the mixin is included and we don’t pass an argument, the compiler will use the default value.

To create a default value, we define our parameters with a value the same way we would a normal variable.

Example: SCSS
@mixin identifier($param_1: default_value, $param_2: default_value) {
  property: $param_1;
  property: $param_2;
}

To demonstrate, let’s add some default values to our “border-solid” mixin that we created earlier. We will also include the mixin without specifying any arguments in the parameter list.

Example: SCSS
@mixin border-solid($width: 2px, $color: #ccc) {
  border: $width solid $color;
}

nav {
  @include border-solid();
}

Because we didn’t specify arguments in the parameter list when we included the mixin, the compiler used the defaults.

Output: Compiled CSS
nav {
  border: 2px solid #ccc;
}

If a mixin is defined with multiple parameters and we only want to specify an argument for one of them, we have to specify that parameter’s name.

Example: SCSS
nav {
  @include border-solid($color: #000);
}

In the example above, we tell the compiler we only want to pass a value to the $color parameter.

It will use the default value for $width , but #000 for $color .

Output: Compiled CSS
nav {
  border: 2px solid #000;
}

Functions

Sass functions are similar to mixins in that they allow us to reuse sections of code.

There are three differences between functions and mixins.

  1. Functions use the @function rule instead of the @mixin rule.
  2. Functions can return a single value back to the user.
  3. Functions are not @included but rather invoked, or called.

To return a value from a function, we use the @return rule, followed by the value we want to return.

Syntax: SCSS function
@function function_name(parameters) {
  // code block

  @return value;
}

Let’s see an example of a function that calculates the square root of a number by multiplying it by itself. The function then returns the calculated value for us to use.

Example: SCSS function
@function sqr($num) {
  @return $num * $num;
}

To use a function we omit the @include rule and simply invoke the function with its name and parameter list.

Example: SCSS invoke function
@function sqr($num) {
  @return #{$num * $num}px;
}

body {
  font-size: sqr(4);
}

In the example above we call the function to have its returned value act as the value for the font-size property. The compiled CSS will look as follows.

Output: Compiled CSS
body {
  font-size: 16px;
}

We don’t have to use the returned value from a function directly, we can assign it to a variable to use later or for further modification.

To do this, we invoke the function as the value to the variable we want to store it in.

Example: SCSS
@function sqr($num) {

  @return #{$num * $num}px;
}

$squared: sqr(4);

body {
  font-size: $squared;
}

In the example above we define a variable called $squared with the sqr() function call as the value. The value that’s returned from the function will be assigned to the variable.

Functions vs Mixins

There is often some confusion on when to use functions, and when to use mixins.

  • Mixins are used for what’s known as side-effects, like setting global variables.
  • Functions are used to compute values.

You should mostly use mixins, unless you need complex custom logic and calculations.

note It’s considered bad practice to use functions for side-effects and is heavily discouraged.

Built-in functions

Sass provides us with several built-in functions that we can use instead of creating our own.

We cover these functions in the Built-in Functions lesson .

Summary: Points to remember

  • A mixin is a reusable collection of style properties and is defined with the @mixin rule.
  • We include a mixin with the @include rule where we want the styles to be placed.
    • Mixins aren’t globally available and will have to be imported into the file where we are using them with the @use rule.
  • We can include mixins within the definition of other mixins.
  • Mixins can have parameters that allow us to pass arguments with different values each time a mixin is included.
    • Parameters are simply Sass variables without values.
  • Parameters may have default values that act as a fallback when we don’t specify an argument.
    • Default parameters are Sass variables with values.
    • When passing values to one of multiple parameters, we have to specify the parameter name.
  • Functions are similar to mixins but have a few key differences.
    • Functions are defined with the @function rule instead of the @mixin rule.
    • Functions can return a value back to the user.
    • Functions are invoked, or called, instead of included with @include .
  • Functions are typically used to compute values, and for complex logic. *We should use mixins for side-effects like setting global variables.
  • Sass provides us with many helpful built-in functions.