Are SASS @mixins really that lightweight? And what are %placeholders?
Tags: saas, mixin, css, webdev
Published: 2023-01-10 12:55:06

**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](https://sass-lang.com/documentation/at-rules/mixin).

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:
```scss
@mixin ButtonStyles {
	margin: 0 3px;
	color: white;
	border: none;
	outline: none;
	transition: all .3s ease;
	cursor: pointer;
	display: inline-flex;

	svg {
		width: 15px;
	}
}
```
Alright, and now let's use it with `@include ButtonStyles`!

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

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

.btn_contrast {
	@include ButtonStyles;
	background: yellow;
	width: 60px;
}
```

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:
```css
.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
	}
```
**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:
```scss
%buttonStyles {
	margin: 0 3px;
	color: white;
	border: none;
	outline: none;
	transition: all .3s ease;
	cursor: pointer;
	display: inline-flex;

	svg {
		width: 15px;
	}
}
```

**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:
```sass
.btn_primary {
	@extend %buttonStyles;
	background: black;
	width: 45px;
}

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

.btn_contrast {
	@extend %buttonStyles;
	background: yellow;
	width: 60px;
}
```
And now let's have a look at the result after compiling **SASS** code into **CSS**.

```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
}
```

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
```css
.btn_secondary, .btn_primary, .btn_contrast {
  ...code 
}
```
into this
```css
.buttonStyles, .btn_secondary, .btn_primary, .btn_contrast {
  ...code 
}
```
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.