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.

Here's a table of contents of what you'll learn in this lesson:
(click on a link to skip to its section)

Let's jump right in.

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 in a mixin and then use the mixin each time we need the reset.

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
}
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:
selector {
  @include identifier;
}

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.

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;
}

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 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 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.

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 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 we only want to pass a value to one of multiple parameters, we have to specify the parameter 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_name(parameters) {
  // code block

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

In the example function above we do a simple math calculation and return the result from the function.

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

Example: SCSS
@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.

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 simply use the function call as the variable value.

Example: SCSS
@function sqr($num) {

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

$squared: sqr(4);

body {
  font-size: $squared;
}

In the example above we define a variable with the 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.

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

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

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.