DEV Community

Cover image for Are SASS @mixins really that lightweight? And what are %placeholders?
KemotiaDev
KemotiaDev

Posted on • Updated on

Are SASS @mixins really that lightweight? And what are %placeholders?

Mixins are a powerful feature in Sass that allow you to reuse a set of CSS declarations across multiple selectors.

One of the main advantages of using Mixins is that they can help keep your CSS code organized and maintainable, making it easier to update and maintain styles across a large code base.
However, one concern that some developers have with Mixins is whether they are lightweight to use, and if they add unnecessary bloat to your CSS code.

In this article, we will take a closer look at Mixins in Sass and explore whether they are a lightweight solution for reusing CSS styles.

Let's dive right into it!

I'm assuming that you already have a basic knowledge about what mixins are and how they work. If not, I encourage you to have a look at the official documentation.

Mixins, as mentioned previously, allow you to create a block of code and reuse it later in your application.
Sometimes, I see that people gets temptated to use them as a main provider for their styles.

... which is not a good idea. Let me show you why

Let's assume we have a huge e-commerce store with a plenty of buttons and we have created a mixin, that will share some basic styles among them.

Here's our simple mixin:

@mixin ButtonStyles {
    margin: 0 3px;
    color: white;
    border: none;
    outline: none;
    transition: all .3s ease;
    cursor: pointer;
    display: inline-flex;

    svg {
        width: 15px;
    }
}
Enter fullscreen mode Exit fullscreen mode

Alright, and now let's use it with @include ButtonStyles!

.btn_primary {
    @include ButtonStyles;
    background: black;
    width: 45px;
}

.btn_secondary {
    @include ButtonStyles;
    background: blue;
    width: 60px;
}

.btn_contrast {
    @include ButtonStyles;
    background: yellow;
    width: 60px;
}
Enter fullscreen mode Exit fullscreen mode

What do you think will happen now if you will compile your SASS code into CSS? Try to answer yourself.

  • a) Code from the mixin will not be repeated.
  • b) Code from the mixin will be repeated everytime you call @include ButtonStyles

Well, I bet you already know the answer!
Using a mixin in this particular case will basically copy paste the entire code from that mixin into your code as many times as you @include it.

Here's the result:

.btn_primary {
    margin: 0 3px;
    color: #fff;
    border: none;
    outline: none;
    transition: all .3s ease;
    cursor: pointer;
    display: inline-flex;
    background: #000;
    width: 45px
}

    .btn_primary svg {
        fill: #fff;
        width: 15px
    }

.btn_secondary {
    margin: 0 3px;
    color: #fff;
    border: none;
    outline: none;
    transition: all .3s ease;
    cursor: pointer;
    display: inline-flex;
    background: blue;
    width: 60px
}

    .btn_secondary svg {
        fill: #fff;
        width: 15px
    }

.btn_contrast {
    margin: 0 3px;
    color: #fff;
    border: none;
    outline: none;
    transition: all .3s ease;
    cursor: pointer;
    display: inline-flex;
    background: yellow;
    width: 60px
}

    .btn_contrast svg {
        fill: #fff;
        width: 15px
    }
Enter fullscreen mode Exit fullscreen mode

Not very efficient if you want to optimize your CSS weight.

Imagine how bloated the code can become, if you'll do it many times in your application.

Well... how to solve it then?

Answer is pretty simple. If you want to keep the idea of having a single block that you can reuse in your Sass code, use placeholder.

%placeholder

Don't be mislead by the name, it's not an HTML placeholder you put into your inputs, it's a SASS placeholder with % sign attached to it's name.

Example:

%buttonStyles {
    margin: 0 3px;
    color: white;
    border: none;
    outline: none;
    transition: all .3s ease;
    cursor: pointer;
    display: inline-flex;

    svg {
        width: 15px;
    }
}
Enter fullscreen mode Exit fullscreen mode

SASS placeholder is the most efficient way of creating your styles template, because it doesn't get compiled into your CSS code and is never repeated.
Also, you can't use @include like you do with Mixins, with placeholder you use @extend keyword instead.

Curious to see how does it work in practice?
Here we go!

Let's first @extend desired styles in our buttons:

.btn_primary {
    @extend %buttonStyles;
    background: black;
    width: 45px;
}

.btn_secondary {
    @extend %buttonStyles;
    background: blue;
    width: 60px;
}

.btn_contrast {
    @extend %buttonStyles;
    background: yellow;
    width: 60px;
}
Enter fullscreen mode Exit fullscreen mode

And now let's have a look at the result after compiling SASS code into CSS.

.btn_secondary, .btn_primary, .btn_contrast {
    margin: 0 3px;
    color: #fff;
    border: none;
    outline: none;
    transition: all .3s ease;
    cursor: pointer;
    display: inline-flex
}

    .btn_secondary svg, .btn_primary svg, .btn_contrast svg {
        width: 15px
    }

.btn_primary {
    background: #000;
    width: 45px
}

.btn_secondary {
    background: blue;
    width: 60px
}

.btn_contrast {
    background: yellow;
    width: 60px
}
Enter fullscreen mode Exit fullscreen mode

And voilà!
Your CSS code is much lighter since nothing there was repeated.
This is super useful in large applications, where each kb matters.

Alternatively to a %placeholder you can use .class instead and extend it similarly by @extend .buttonStyles but this will result in applying this class name to the css class names list.
In our case scenario it would change this

.btn_secondary, .btn_primary, .btn_contrast {
  ...code 
}
Enter fullscreen mode Exit fullscreen mode

into this

.buttonStyles, .btn_secondary, .btn_primary, .btn_contrast {
  ...code 
}
Enter fullscreen mode Exit fullscreen mode

Note the .buttonStyles class applied to the classes list.
It's not a bad solution, but since you are already extending styles, why not do it perfectly?
Moreover, if you really care about every kb, you might save a bunch by not having unused class names in class lists.

Conclusion
Mixins in Sass are a great way to reuse CSS styles, but they can add unnecessary bloat to your CSS code if they are not used carefully.
An alternative approach to using Mixins is to use placeholders. Placeholders allow you to reuse a set of CSS declarations without generating any actual CSS code.
Instead, they are only used as a reference and only generate code when they are referenced by other selectors. This can help keep your CSS code more efficient and lightweight. By using placeholders instead of Mixins, you can ensure that your CSS code is lean and efficient, making your web application faster and more responsive for your users.

Top comments (2)

Collapse
 
aileenr profile image
Aileen Rae

Nice, I wasn't aware of placeholders in SASS. I also wasn't familiar with how mixins transpiled into CSS. TIL - thank you! ✨

I think for the specific button use case you describe I would rely on plain CSS. I'd add the base styles to a btn class, then add the extended styles to btn-primary, btn-secondary etc. That does mean you'd need to add two classes to your markup though e.g. class="btn btn-primary", so it's cool to see an alternative.

Collapse
 
kemotiadev profile image
KemotiaDev

Hi Aileen.
I'm happy that I could show you something new :)

Yes, SASS placeholders are not widely used even though they are pretty great.

When it comes to buttons styling, the way you described is also what I would go for during real life development.
My example is just to show the idea and I think everyone had styled at least one button in his life :) and that makes the example much easier to understand.

Have a great day!