Screw @mixin, use @extend!
I see a lot of people using the Sass @mixin in ways that makes for really bad and repetitive code when compiled into CSS. Fear not, Sass has a solution!
The Sass @extend allows you to, as the name implies, let selectors inhert code from other selectors. This compiles way nicer than using @mixin for the same purpose, and you still retain code maintainability.
With @mixin
Sass
@mixin button {
width: 50px; height: 50px;
margin: 10px;
padding: 10px; }
.button {
@include button;
color: black;
border: 1px solid black; }
.button-red {
@include button;
color: red;
border: 1px solid red; }
.button-blue {
@include button;
color: blue;
border: 1px solid blue; }
Compiled code
.button {
width: 50px; height: 50px;
margin: 10px;
padding: 10px;
color: black;
border: 1px solid black; }
.button-red {
width: 50px; height: 50px;
margin: 10px;
padding: 10px;
color: red;
border: 1px solid red; }
.button-blue {
width: 50px; height: 50px;
margin: 10px;
padding: 10px;
color: blue;
border: 1px solid blue; }
With @extend
Sass
.button {
width: 50px; height: 50px;
margin: 10px;
padding: 10px;
color: black;
border: 1px solid black; }
.button-red {
@extend .button;
color: red;
border: 1px solid red; }
.button-blue {
@extend .button;
color: blue;
border: 1px solid blue; }
Compiled code
.button, .button-red, .button-blue {
width: 50px; height: 50px;
margin: 10px;
padding: 10px;
color: black;
border: 1px solid black; }
.button-red {
color: red;
border: 1px solid red; }
.button-blue {
color: blue;
border: 1px solid blue; }
The output we get from using @extend follows the DRY principle, leaving a much smaller footprint in the compiled CSS. Only using @mixin could easily leave your CSS in a mess, even though the Sass looks good.
You could also use @extend to make the HTML more readable:
instead of
.link {
width: 50px; height: 20px;
padding: 3px;
color: black;
display: block; }
.link-red {
color: red; }
<div class="link"></div>
<div class="link link-red"></div>
<div class="link"></div>
You could do
.link {
width: 50px; height: 20px;
padding: 3px;
color: black;
display: block; }
.link-red {
@extend .link;
color: red; }
<div class="link"></div>
<div class="link-red"></div>
<div class="link"></div>
When inheriting styles, screw @mixin, use @extend!
Source: http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#extend
Written by Håkon Ellingsen
Related protips
3 Responses
Two things:
2) If you need to include any kind of variable, you MUST use mixins. So don't discount them entirely. Also, if you're not careful, @extend
becomes a nasty, slippery slope.
@ultimatedelman I did not know about the placeholders, but it is really helpful. Makes @extend even more powerful! Haven't gone all the way through the docs yet after I decided to relearn Sass properly, so I really appreciate this tip!
Not using @mixin at all wasn't really the point of my tip though. Me and a friend was just really tired of seeing @mixin being used everywhere and for everything, completely ruining the DRYness we both have come to love. @mixin certainly got its place when writing meaningful and maintainable Sass, and my code still utilize them heavily.
Was about to add extend placeholders - probably worthwhile adding to this tip - as it's probably the closest behaviour to what your mixin will achieve (e.g. the mixin itself does not emit output).