Let’s Learn SASS & SCSS: Diving Deeper into Mixins & Extends(Part 5)

Mixins and extends are cool, right? In our last article, we dived into the basics of both and have a good idea of what they are. In short: extends and mixins are great for reusing blocks of styles. Mixins can even perform calculations before returning the value.

The problem is, you might not know how to apply them to your project. In this article, I plan to dive into practical ways to implement both mixins and extends. You may have some ideas already! If not, I hope to give you a good starting point to bounce ideas off of. No need to waste time, let’s dive in!

What Can You Use Extends For?

Extends have no real limit on what you use them for. As mentioned, you should use them whenever you see a block of styles that can be repeated. A common example is centering and aligning HTML elements. If you use something like flexbox, you probably use certain styles across many elements. Defining those 3-4 lines repeatedly across your entire code base can get repetitive quickly. That’s an opportunity to use extends to your advantage!

Some other examples include defining certain font weights with custom fonts, combinations of line height and font size patterns, and column layout code. I will dive into some of these in a minute. Before we do, let’s imagine an ideal folder structure for your @extends.

How Can You Structure Extends?

Short answer: however you want. Though, I’ll show you how I’d approach it. I make all of my @extends global and one of the first things I import in my main.scss file. A folder structure might look something like this:

scss - The folder with all of your scss code.
    ...
    extends - Main extends folder
        main.scss - The main folder for @including all of your extends
        layout.scss - Extends for general layouts
        buttons.scss - Define common button colors/hover states
         ... - And so on

You can also define @extends in different parts of your app if you’re only going to use them in certain files. For example, if you have a repeatable block across blog pages, you can define @extends at the _main.scss file in your blog folder. It will be easier to know what the @extends are for if you see they are in a specific folder.

I usually use a combination of both, but once again, do what works for you!

Defining Fonts

If you use custom fonts that aren’t loaded from some kind of cdn such as Google fonts, you likely have to import all font weights yourself. You’ll often have dedicated fonts for each weight such as bold, italic bold, light bold, regular, and so on. If you use a font such as AvenirNext, you’d define fonts like this:

// Use our font mixin helper from earlier
@include font('AvenirNext Bold');
@include font('AvenirNext Regular');
@include font('AvenirNext Demibold');
@include font('AvenirNext Italic Bold');
// ... and so on

Not that the actual font names will vary based on how you define them. Chances are, you’ll want to use these throughout the code base in varying amounts depending on the design. Instead of memorizing the specific font name, you can put each weight into it’s own @extend.

// Note that you can use mixins inside of extends
%font-bold {
    @include font('AvenirNext Bold');
}

%font-regular {
    @include font('AvenirNext Regular');
}

// Using them now only requires a reference to the extend
.element .text-section p {
    @extend %font-regular;

    &.bolded {
        @extend %font-bold;
    }
}

Another benefit of this approach is being able to change the font values in their own extend, thus updating every instance throughout the code base in one fell swoop. Useful if your website ever changes the font scheme.

Defining Reusable Columns

It’s common to have 2, 3, and 4 column layouts on generic elements throughout your app. This code tends to be repeatable, so hey, it’s another great case for an extend! I actually wrote out how to do this here. I’d urge you to check it out since it can save lots of code if you’re not relying on a third party framework such as Bootstrap. It’s also fairly easy to implement and works with only a few HTML classes.

Extends are pretty flexible to the point where I can’t cover every possible use case. However, I’m sure you’ll find some creative ways to cut down on development code and time. Let’s move on to an even more powerful SASS utility: SASS mixins.

What Can You Use Mixins For?

As we discussed, mixins are like extends with dynamic values. Despite the fairly small difference, this opens up a lot of useful utilities you can make. There are also additional SASS utilities you can use with mixins such as @content. We will cover this shortly. Examples include various repeatable UI elements that can have a variable color/width/height. Mixins can also be used for utilities such as media queries, spacing, and layouts. Let’s look at how we can structure mixins, then some examples!

How Can You Structure Mixins?

You can structure them very similarly to extends. Have a base file, then split them up into their own utility files. Here’s a quick example:

mixins - The main entry folder. Likely a sibling with the extends folder.
    _main.scss - Main entry file that contains all @imports
    _general.scss - Add mixins that don't fit into a particular folder
    _buttons.scss - Button specific mixins
    _ui.scss - General UI mixins
    ... - And so on

The @content Block

One very useful SASS utility is the ability to pass content off into a mixin. Instead of passing values through a parameter, you can pass content through the block itself. Let’s see an example using a media query. When you define a media query, you usually need to define the screen conditions and a max-width or min-width.

@media screen and (max-width: 768px) {
    // your styles here
}

// Heres a media query for targeting newer IE browsers
@media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {
     // your styles here
}

Defining these media queries can be pretty verbose. Luckily, we can easily abstract them using the @content block.

@mixin ifIE() {
  @media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {
     @content; // Whatever styles are between the brackets will be passed through here
  }
}

@mixin atTablet() {
  @media screen and (max-width: $tablet) {
    @content; // Whatever styles are between the brackets will be passed through here
  }
}

// Apply these styles only on tablet sized screens
.container {
    @include atTablet {
        // These styles are passed through the @content block for the atTablet mixin
        display: flex;
        align-items: center;
    }
}

I wrote more in depth on this topic here if you want to check it out! Once you have the main logic figured out for your breakpoints, it’s easy to port across any project.

Reusing UI Elements

There are many cases where you want to use similar blocks of styles throughout your site’s components. You can do these with @extends, but mixins allow you to pass in dynamic color and size values.

Custom Scrollbar
The default scrollbar can actually be changed on most browsers! You’re generally not supposed to change the regular scrollbar for UX reasons, but it’s pretty common to make custom scrollbars for inner elements such as blocks of text or cards. Defining the cross browser code is normally verbose, so let’s abstract it.

@mixin scrollbar($color, $size) {
  scrollbar-width: $size;
  scrollbar-color: $color;

  &::-webkit-scrollbar {
    width: $size;
    height: $size;
  }

  &::-webkit-scrollbar-thumb {
    background: $color;
  }
}

.container .inner-card {
    @include scrollbar('blue', 3.5px);

    &--red-scrollbar {
        @include scrollbar('red', 3px);
    }
}

See the potential here? Whenever you want to define a custom scrollbar, instead of worrying about the cross browser specifics, you just call it with one line of code! You can make these kinds of UI elements as customizable as you want. In this example, the color and size are customizable. If you have other needs for parameters, it only takes an extra argument!

That’s About It!

Though we covered more advanced examples, there’s still lots of potential for @extends and @mixins. My hope is that you take the examples here and get ideas for implementing them in your own projects. There’s lots more to explore that I plan to cover in the future. For now, let’s take a break and dive into other useful SASS features. Hope to see you there!

Comments