7p7w2a
Last Updated: August 09, 2016
·
31.36K
· rachelnabors
150 twitter

When to use Sass mixins, extends and variables

Recently had a conversation on Twitter that reminded me that what is apparent to some old hats might be obscure to those just diving into Sass. Here are my rules of thumb on when to use mixins, extends, and variables.

Variables

Use a variable when you have a single value you'd like to store. For instance:

$color: #444;
$width: 4em;

.module { 
  color: $color; 
}

Compiles to:

.module {
  color: #444; 
}

Extends

Use @extend when you want to store multiple static properties and pass them to selectors:

.module { 
  background: #fff;
  color: #444; 
}

.main_module { 
  @extend .module;
  min-height: 3em;
}

.sidebar_module { 
  @extend .module;
  min-height: 2em;
}

Compiles to:

.module, .main_module, .sidebar_module {
  background: #fff;
  color: #444; 
}

.main_module { 
  min-height: 3em;
}

.sidebar_module { 
  min-height: 2em;
}   

Mixins

Mixins always compile to CSS rules where they appear in code. Where an @extend generates more selectors, @mixin always generates more rules. Observe the above as a mix-in:

@mixin module {
background: #fff;
color: #444;
}

.main_module { 
  @include module;
  min-height: 3em;
}

.sidebar_module { 
  @include module;
  min-height: 2em;
}

Compiles to:

.main_module { 
  background: #fff;
  color: #444; 
  min-height: 3em;
}

.sidebar_module { 
  background: #fff;
  color: #444; 
  min-height: 2em;
}   

This is why for static rules it is often (not always) less bloaty to use @extend.

As a rule of thumb, I only use mixins to do "mathy" things. "If it doesn't need to pass variable, it doesn't need to be a mixin" is my motto:

@mixin module($parent-color) { 
  color: darken($parent-color, 50%); 
}

.main_module { 
  @include module(#ccc);
  min-height: 3em;
}

.sidebar_module { 
  @include module(#444);
  min-height: 2em;
}

Compiles to something like:

.main_module { 
  color: #999; 
  min-height: 3em;
}

.sidebar_module { 
  color: #000; 
  min-height: 2em;
}   

12 Responses
Add your response

3834
Headshot cropped800

Thanks for the succinct explanation of the differences.

If I want to use a set of rules and @extend them, but don't want the base class to show up anywhere, I use the "%" operator.

%module { } means that the class ".module" won't show up in the output anywhere.

over 1 year ago ·
3836
150 twitter

@pe1999 Exactomundo!

over 1 year ago ·
3837
150 twitter

@pe1999 Exactomundo!

over 1 year ago ·
3838
D42a7264714dee5006b9c99d2567a320

I would also use a mixin for something like clearfix or other css hack.

over 1 year ago ·
3839
Headshot cropped800

@dpashkevich A SASS tool like Compass helps in this avenue, as it has many, many common ones built in, plus other useful mixins like responsive grid libraries (We recommend Susy). Worth checking out if you are not familiar.

over 1 year ago ·
3846
150 twitter

@dpashkevich I beg to differ. I use an extend class for that. Keep selectors short and DRY.

%clearfix { zoom: 1; /*or whatevs*/ }

.container { @extend %clearfix; }

Just works out better for me in the large codebases I've worked on. But that's me.

over 1 year ago ·
3853
D42a7264714dee5006b9c99d2567a320

@pe1999 I'm familiar with Compass, I was just making a point that mixins can be used for "mixing in" some common snippets like clearfix. Thanks for the reference to Susy though!

@rachelnabors that's interesting, thanks for sharing! So the only difference here is that if my .container already has the properties defined in clearfix, they won't appear twice?

over 1 year ago ·
3860
150 twitter

@dpashkevich Right. @extend lets you extend selectors; @mixin is a rules factory.

over 1 year ago ·
4078
2c4b850cf6a0a3be7a18c7840bc12435

Really nice post. I dont usually use extend but I will definitely look into it.

over 1 year ago ·
4171
Fc3bd61bb6315136f4f055a1d2b19972

Very nice. I'm learning Sass, this article will help me.

over 1 year ago ·
8718
5f8886b89696efeb3dcebeee856a1e45

I use a function to do mathy things.
margin: emCalc(10px) would return the em value for the px I use.

In the example of a mixin you have given above, I would have used a function.
Mixins, to me, generally give out a set of CSS rules.
Functions return values that are used inside of a property.

@extend and @include are a great source of confusion. If you have the same item being repeated multiple times (say 50 or above), using @extend could bloat up the selector list on your CSS. Its great for shortening the output and the browsers understand it better.

Unless you're debugging Sass, if you're debugging CSS, you might find it extremely difficult to locate the particular rule declaration.

Because of this same reason, @extend does not work well for grid scss files.
Sometimes it makes more sense to use an @include when you want the output to be together.

over 1 year ago ·
15120
B0b841629a93dce04ba6bf9fabad8e9c

Very helpful and succinct explanation. Thanks.

over 1 year ago ·