Skip to main content

Sass: @mixin Directive and @include Directive

@mixin Directive

Mixins allow you to define styles that can be re-used throughout your stylesheet.

Mixins are defined using the @mixin at-rule, which is written @mixin <name> { ... } or @mixin name(<arguments...>) { ... }.

A mixin’s name can be any Sass identifier, and it can contain any statement other than top-level statements.

  • They can be used to encapsulate styles that can be dropped into a single style rule
  • They can contain style rules of their own that can be nested in other rules or included at the top level of the stylesheet
  • they can just serve to modify variables

@include Directive

Mixins are included into the current context using the @include at-rule, which is written @include <name> or @include <name>(<arguments...>), with the name of the mixin being included.

Example @mixin and @include

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

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

li {
display: inline-block;
margin: {
left: -2px;
right: 2em;
}
}
}

nav ul {
@include horizontal-list;
}

and the generated style.css output is

nav ul {
margin: 0;
padding: 0;
list-style: none;
}
nav ul li {
display: inline-block;
margin-left: -2px;
margin-right: 2em;
}

Mixin Arguments

Mixins can also take arguments, which allows their behavior to be customized each time they’re called.

The arguments are specified in the @mixin rule after the mixin’s name, as a list of variable names surrounded by parentheses.

Example:

@mixin rtl($property, $ltr-value, $rtl-value) {
#{$property}: $ltr-value;

[dir=rtl] & {
#{$property}: $rtl-value;
}
}

.sidebar {
@include rtl(float, left, right);
}

and the generated style.css output is:

.sidebar {
float: left;
}
[dir=rtl] .sidebar {
float: right;
}

Optional Arguments

You can make an argument optional by defining a default value which will be used if that argument isn’t passed.

Default values use the same syntax as variable declarations: the variable name, followed by a colon and a SassScript expression.

@mixin replace-text($image, $x: 50%, $y: 50%) {
text-indent: -99999em;
overflow: hidden;
text-align: left;

background: {
image: $image;
repeat: no-repeat;
position: $x $y;
}
}

.mail-icon {
@include replace-text(url("/images/mail.svg"), 0);
}

and the .css output:

.mail-icon {
text-indent: -99999em;
overflow: hidden;
text-align: left;
background-image: url("/images/mail.svg");
background-repeat: no-repeat;
background-position: 0 50%;
}

Keyword Arguments

When a mixin is included, arguments can be passed by name in addition to passing them by their position in the argument list.

Keyword arguments use the same syntax as variable declarations and optional arguments.

@mixin square($size, $radius: 0) {
width: $size;
height: $size;

@if $radius != 0 {
border-radius: $radius;
}
}

.avatar {
@include square(100px, $radius: 4px);
}

and the .css output:

.avatar {
width: 100px;
height: 100px;
border-radius: 4px;
}

Taking Arbitrary Arguments

Sometimes it’s useful for a mixin to be able to take any number of arguments. If the last argument in a @mixin declaration ends in ..., then all extra arguments to that mixin are passed to that argument as a list. This argument is known as an argument list.

@mixin order($height, $selectors...) {
@for $i from 0 to length($selectors) {
#{nth($selectors, $i + 1)} {
position: absolute;
height: $height;
margin-top: $i * $height;
}
}
}

@include order(150px, "input.name", "input.address", "input.zip");

and the .css output

input.name {
position: absolute;
height: 150px;
margin-top: 0px;
}

input.address {
position: absolute;
height: 150px;
margin-top: 150px;
}

input.zip {
position: absolute;
height: 150px;
margin-top: 300px;
}