HTML & CSS
Article

Sass Basics: The Mixin Directive

By Reggie Dawson

For me finding Sass was a revelation. For the longest time I had tired of writing plain or ‘vanilla’ CSS. For a small site it was fine, but for larger sites the CSS quickly got out of hand. Debugging was a nightmare and I couldn’t help but feel like I could do more with my CSS.

I found Sass and everything changed. With Sass I could break my CSS down into modular chunks to make troubleshooting a breeze. I could also use programming concepts, such as functions and variables, when creating my CSS. And most importantly Sass introduced me to Mixins.

What is a mixin?

A mixin allows us to create reusable chunks of CSS. Being able to do this helps us to avoid writing repetitive code. For example:

a:link { color: white; }
a:visited { color: blue; }
a:hover { color: green; }
a:active { color: red; }

Writing this code over and over again can get old very quickly, especially of you have a large site with a lot of links. With a mixin creating link can be done with Sass like this.

@mixin linx ($link, $visit, $hover, $active) {
  a {
    color: $link;
    &:visited {
      color: $visit;
    }
    &:hover {
      color: $hover;   
    }
    &:active {
      color: $active;
    }
  }
}

How to include a mixin

To make use of a mixin you have to include it in your Sass files. To call the link mixin from above we would add this line.

@include linx(white, blue, green, red);

The @include directive allows you to use mixins within your Sass files.

How to create a Mixin

To create a mixin you use the @mixin directive. For example:

@mixin sample {
  font-size: 12px;
}

You define this directive by using @mixin followed by the name of the mixin. You can also optionally include arguments in your mixin, such as with the linx mixin from above.

You can also use variables defined elsewhere in your Sass files inside the mixin too. Lets say we wanted to use $font-base as a variable in our mixin. As long as our variable has been defined we can use it in our mixin.

$font-base: 12px;

@mixin sample {
  font-size: $font-base;
}

p {
  @include sample;
}

The resulting CSS is:

p {
  font-size: 12px;
}

Arguments

A mixin can take Sass data values as arguments. These values are specified when you define the mixin and given when you @include the mixin. The arguments are then passed to the mixin as variables. Arguments are included in a comma separated list enclosed in parentheses after the mixin name.

@mixin headline ($color, $size) {
  color: $color;
  font-size: $size;
}

h1 {
  @include headline(green, 12px);
}

This will compile to

h1 {
  color: green;   
  font-size: 12px;
}

When using basic arguments, they have to be called in the order specified in the mixin. In the last example, if we switched the order of arguments when including the mixin:

h1 {
  @include headline(12px, green);
}

h1 {
  color: 12px;
  font-size: green;
}

As you can see that doesn’t work. The mixin just delivers the arguments in the order given. You can also pass Sass variables as arguments. For example lets say we set a $base-color variable in the above example.

$base-color: pink;

@mixin headline($color, $size) {
  color: $color;
  font-size: $size;
}

h1 { @include headline($base-color, 12px);}

Which will compile to:

h1 {
  color: pink;
  font-size: 12px;
}

Default Values

When creating your mixin you can specify default values for your arguments. When default values are included you can omit passing that value when calling your mixin. The default value will be used. For example if I update the headline mixin from above with a default value.

@mixin headline($size, $color: red) {
  color: $color;
  font-size: $size;
}

h1 {
  @include headline(12px);
}

h1 {
  @include headline(12px, blue);
}

Compiles to

h1 {
  color: red;
  font-size: 12px;
}
h1 {
  color: blue;
  font-size: 12px;
}

In the first h1 we specified a pixel size, so the default value of red was used. In the second example the default value was replaced by the provided color of blue we used in our @include. Note that we had to change the order of arguments as Sass wants to specify required arguments first. Since the $color argument has a default value, specifying a color in the @include is optional. We can also specify a variable as a default value.

$base-color: orange;

@mixin headline($size, $color: $base-color) {
  color: $color;
  font-size: $size;
}

Keyword Arguments

We also have the option of including our mixin with keyword arguments. However, even if it can make our code less concise it will improve readability, which is important if someone else will be maintaining the code you have written. We can also include our arguments in any order, and of course default values can be omitted.

@mixin headline($size, $color: red) {
  color: $color;
  font-size: $size;
}

h1 {
  @include headline($color: blue, $size: 12px);
}

This compiles fine even though the arguments are in the wrong order.

h1 {
  color: blue;
  font-size: 12px;
}

Variable arguments

Sometimes you may need your mixin to accept a number of arguments. For example the padding property can have from one to four arguments. In this situation you could create a mixin that uses variable arguments. Variable arguments allow you to package up arguments as a list. The variable arguments look like regular arguments for a mixin except they add (…) at the end.

@mixin pad ($pads...) {
  padding: $pads;
}

.one {
  @include pad(20px);
}
.two {
  @include pad(10px 20px);
}
.three {
  @include pad(10px 20px 40px);
}
.four {
  @include pad(10px 20px 30px 20px);
}

Compiles to:

.one {
  padding: 20px;
}
.two {
  padding: 10px 20px;
}
.three {
  padding: 10px 20px 40px;
}
.four {
  padding: 10px 20px 30px 20px;
}

We can also include regular arguments next to our variable arguments. Lets say we wanted to set a text color in our pad mixin.

@mixin pad ($color,$pads...) {
  color: $color;
  padding: $pads;
}
.four { @include pad(orange, 10px 20px 30px 20px); }

Which generates

.four {
  color: orange;
  padding: 10px 20px 30px 20px;
}

The regular arguments have to come before the variable arguments. As you can see the leftover arguments are packaged up and used for the padding values. We can also use variable arguments when including our mixin. We can draw from a list of values or a map for our arguments.

$box-style1: 5px, solid, red;
$box-style2: (bStyle: dotted, bColor: blue, bWidth: medium);

@mixin boxy($bWidth, $bStyle, $bColor) {
  border-width: $bWidth;
  border-style: $bStyle;
  border-color: $bColor;
}

.first {
  @include boxy($box-style1...);
}

.second {
  @include boxy($box-style2...);
}

As you can see we have setup a list and a map to use for our mixin. When using a list the arguments have to be in the correct order, same as when we are using basic arguments with our mixin. When using a map it doesn’t matter as the map values will be treated like keyword arguments, and as you can see I gave the map values in the wrong order. We still end up with:

.first {
  border-width: 5px;
  border-style: solid;
  border-color: red;
}

.second {
  border-width: medium;
  border-style: dotted;
  border-color: blue;
}

@content

You are also able to pass a block of styles not defined in the mixin through the @content directive. These additional styles will appear within the mixin where you place @content.

@mixin cont {
  background-color: black;
  color: white;
  @content;
}

Now when we call this mixin we can add any additional properties we want to use:

div {
  @include cont {
      font-size: 12px;
      font-style: italic;
  }
}

div {
  background-color: black;
  color: white;
  font-size: 12px;
  font-style: italic;
}

As you can see the font size and style we added has been incorporated into our styling for the div. The @content directive allows you to setup base styles and customize as needed.

Conclusion

As you can see mixins can be very useful in your Sass. There is so much you can accomplish with mixins to speed up your work flow. For more info on how to use mixins and Sass in general check out sass-lang.com. What are your favourite mixins? Please share them in the comments.

Free Guide:

7 Habits of Successful CTOs

"What makes a great CTO?" Engineering skills? Business savvy? An innate tendency to channel a mythical creature (ahem, unicorn)? All of the above? Discover the top traits of the most successful CTOs in this free guide.

Comments
FrontendGuru

Thank you Reggie for this article ! It's a good explanation of the strengths of Sass Mixins.

Unfortunately your Padding-Mixin isn't correct. You can't separate the values with a comma in the output.

Reggie

Good catch FrontendGuru. The mixin works, its my usage that is the problem. I was supposed to call the mixin like this:

@include pad(10px 20px 30px 20px);

Sass takes a list of values separated by commas or spaces, and in this example I was supposed to use spaces so that compilation doesn't use commas.

Was correct initially but I changed while editing, what I get for working late at night. Thanks for the feedback, I will submit a correction.

sturobson

Thanks for catching this, I've just updated the article so that the examples are now correct. I'm really pleased you liked it.

PauloFrancaLacerda

Loved it. Thank you so much for the article. I helped me a lot.

Recommended
Sponsors
Because We Like You
Free Ebooks!

Grab SitePoint's top 10 web dev and design ebooks, completely free!

Get the latest in Front-end, once a week, for free.