Using @extend in your SASS Mixins

Grrr!!!!
It’s not as good as a Reeses, but combining @extend and mixin be can pretty sweet.

Admittedly, it took me too long to understand @extend in SASS. I’m not sure why, but it did. mixins I got right away, reminding me of my Flash days (oh so long ago) and the first function I wrote. It felt like I’d broken into another dimension. Variables in and out, changing stuff on the fly. It was a little machine made of code.

The problem is a mixin isn’t always an efficient “machine.” Every place you use a mixin in your style sheet, when complied, dumps out all its code. Thus, if not used correctly, your style sheet file is larger with replicated styles and makes for clunky, bloated css. So let’s use @extend. We only declare it once and the element styles are actually “cascading,” making for a cleaner and smaller file. But @extend doesn’t allow for variables, and calling an @extend class, only to override the styles (e.g., changing the background color), kind of defeats the purpose of using @extend.

If only we could harness the power of the mixin and @extend!

We can! Hallelujah! Alright, alright, it’s not life changing, but pretty cool nonetheless.

So mixins. We have a basic style and then “mix” it up by changing the variables. For example:

=my-button($bg-color: blue)
  display: inline-block
  padding: 1em 2em
  background: $bg-color

Now it’s super easy to change links into buttons wherever I want.

a
  +my-button(green)

header a
  +my-button(red)

But like I said earlier, using the mixin like this replicates code in the compiled css file:

a {
  display: inline-block;
  padding: 1em 2em;
  background: green;
}

header a {
  display: inline-block;
  padding: 1em 2em;
  background: red;
}

No good. I want to have the ability to easily change the background color with the conciseness of using @extend. So I’ll combine them, taking the foundational styles of the +my-button mixin and create a new class with the those styles to use as an @extend class.

.my-button-basic
  display: inline-block
  padding: 1em 2em

//I’ll add that to the `mixin`.

=my-button($bg-color: blue)
  @extend .my-button-basic
  background: $bg-color

// Now apply the styles

a
  +my-button()

header a
  +my-button(red)

Here’s the output when compiled.

a, header a {
  display: inline-block;
  padding: 1em 2em;
}

a {
  background: blue;
}

header a {
  background: red
}

Now when I call the mixin, I’m only generating the background color with the @extend class sitting in one place in the css, happily doling out its style to all elements who want it.

The above examples are using just a few properties, so it might seem overkill. But when you have complicated mixins with states and child selectors and lots of properites, they can get pretty gnarly. Combining @extend and mixin will keep your code cleaner, your file size smaller, and even make global changes easier.

comments powered by Disqus