SASS provides two main ways to reuse styles — @extend and mixins — this article is a brief look into how both work and which to use.

TLDR: @extend with/without placeholders are best when you have shared static, similar styles but they cause duplicate classes while mixins are best for dynamic styles which uses passed arguments but they lead to repeated declarations.

@extend

The extends syntax allows you to share styles between two selectors. It’s analogous to the way classes are combined in HTML.

Using @extend , this can be written as:

Simple usage of `@extend`.

The .seriousError selector is initially grouped with the .error selector (which contains the extended styles). The remaining .seriousError properties are then grouped below.

But, what if you don’t need the .error class to be compiled? Perhaps, it’s just a shared utility class/constructor? Then, you can use placeholder selectors e.g. %foo which unlike the .error selector above, won’t be compiled which is great for utility/shared classes that will never be used in the markup. For example:

Using extend with placeholders. Notice, how the “%foo” placeholder is not compiled in the final output?

Mixins

Mixins are quite similar to extends, for example, using mixins, we could have done this:

Like extend using placeholders, the error mixin isn’t included in the compiled version. Unlike extend though, notice how the declarations in the error mixin are repeated multiple times in the compiled version? Sheesh. That’s maybe not good?

Then again, this is not exactly what mixins were intended for. The true magic in mixins arise from the fact that you can pass in arguments, just like a function call. For our error mixin, we can provide different background colors for different type of errors:

Which should you use?

Like everything frontend related, it depends on your use case and the tradeoffs you require.

Generally, if you don’t have dynamic styles, using @extend (preferably using placeholders — unless you are referencing the class in the DOM) is good enough. Using mixins for static-only styles causes unnecessarily bloated stylesheets so it’s a good idea to keep the declarations minimal and only for dynamic declarations because it’s going to be duplicated.

On Composes

composes from CSS Modules is also an interesting option and leads to duplicate classes — like @extend — but unlike extend, these duplicated classes will be in the markup (not the stylesheet).

Examples are from the SASS documentation on @extend and mixins.

SASSMeister — Repl for SASS