Last Updated: February 25, 2016
·
1.781K
· ellinokon

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

3 Responses
Add your response

Two things:

1) @extend Placeholders

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.

over 1 year ago ·

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

over 1 year ago ·

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

over 1 year ago ·