Let’s Learn SASS & SCSS: Extending your knowledge with @extends and @mixins (Part 4)

There are 3 posts before this article, checking them out might provide additional context for this article. You can check out part 1 (getting up and running), part 2 (setting up a build), and part 3 (variables and nesting).

Now that we’ve covered all of the SASS basics, it’s time to dive into the more advanced features! There are two main features we will cover in this article: extends and mixins. Both of these allow you to reuse similar blocks of styles. If you’ve done any kind of extensive CSS development, you know how repetitive some code can get.

SASS is here to help you chop down some development time and grant you more efficient code. Let’s dive into the first of the two: extends.

What are extends?

The name is in the title: @extends allow you to extend a selector with specific styles. You typically define @extends in a separate file (but you don’t have to) and reuse them throughout your app. Kind of like variables! SASS extends work a bit like variables, but they can contain as much code as you need them to. Let’s dive into a simple example.

%flex-center {
    display: flex;
    justify-content: center;
    align-items: center;
}

.container .center {
    @extend %flex-center;
}

.container2 .content-container {
    @extend %flex-center;
}

In this example, both .container .center and .container2 .content-container will receive the styles defined in %flex-center. Using the @extend keyword, you can extend any block of code, as long as it’s defined beforehand. Usually, extends are defined in a global file, but can certainly be defined in the same file locally.

To define an extend, just define the name of it with a % symbol preceding it. Look at the %flex-center in the example above for reference. That’s where we defined the extend. You can use as many @extends as you want, as many times as you want. In the example, we call the extend when we use something like @extend %flex-center.

%flex-center {
    display: flex;
    justify-content: center;
    align-items: center;
}

%blue-border {
    border: 2px solid blue;
}

.container {
    // You can use as many extends as you desire
    @extend %flex-center;
    @extend %blue-border;
}

Extends aren’t only reserved for styles. You can have selectors inside of your extends too! My own extends tend to be 2-5 lines, but I’ve had large repeatable blocks that have up to 15 lines of styles. They can almost act as styled components. Actual CSS components should be defined in their own files with a selector, but sometimes extends can be added to parts of multiple components.

Similar to variables, if you need to change the style of a text element that shows up 5 times across multiple style components, you can change it in one place.

%dark-text-section {
    padding: 35px 10px;
    background-color: rgba($dark, 0.2);

    .content {
        color: $dark;
    }

    p {
        line-height: 1.5;
    }
}

// Some component file
.component2 {
    .content-container {
        @extend %dark-text-section;
    }
}

// A completely separate component file
.component4 {
    .inner-content {
        @extend %dark-text-section;
    }
}

That’s really all there are to @extends! The concept of them is relatively simple and you may already be thinking of how you can use them for your own code. A basic rule of thumb: if you see the same bits of code repeated across multiple files, they can likely be made into its own block.

While extends are useful, they can be limited in certain situations. What if you want to pass dynamic values into them? What if your code requires a certain calculation to be made before returning the value? Can SASS even do that? It sure can! We’re going to learn about @mixins next. They’re not that different from extends at the end of the day, but they are much more powerful. Let’s dive into it!

What are @mixins?

Mixins are essentially @extends that can take in dynamic values. They’re a lot more like functions than variables. We compared extends to variables because they store static blocks of styles. A %flex-center extend will always return whatever was defined there. Mixins take values(arguments), and return whatever was passed in, or do a potential calculation then return. Let’s see a quick example.

@mixin font($font) {
    font-family: $font, 'Arial', 'Helvetica', 'sans-serif';
}

.open-sans-section {
    @include font('Open Sans');
}

.noto-sans-section {
  @include font('Noto Sans');
}

This mixin is useful for defining a font fallback pattern in one place (the mixin), but allowing a custom font value to be passed in. Notice that a mixin is defined differently than an extend. You define a mixin with @mixin and use parenthesis for passing in the arguments. In the above example: We defined the font mixin like this: @mixin font($font) { ... }

When calling a mixin, use the SASS @include keyword. Example: @include font('Noto Sans'). In this case, 'Noto Sans' is our one argument.

Note that mixins don’t have to have defined arguments. If they do, you need to pass an appropriate amount of arguments into the @include keyword. If you don’t, you’ll get an error!

@mixin no-arguments {
    padding: 50px;
}

@mixin arguments($arg1) {
    padding: $arg1;
}

.add-medium-padding {
    @include no-arguments;
    
    // This will create an error! It needs one argument.
    @include arguments;

    // This is what you'd pass in to give this section a padding value of 50px. No error here
    @include arguments('50px'); // padding: 50px;
}

There’s a lot you can do with mixins, but those are the basics. One last thing I’ll dive in to is performing calculations. Let’s do a basic example here and dive deeper in our next article!

@mixin double-padding($padding) {
    padding: $padding*2;
}

.pad-small {
    padding: 20px;
}

.pad-medium {
    @include double-padding('20px'); // padding: 40px;
}

SASS is able to convert px values and add, divide, or multiply them. This is why we can do something like: 20px*2. This won’t cause any errors! Cool right?

In this example, we can convert a pixel value and double it with a fairly simple line of code. There’s many more conversions you can do and lots of potential there. Nonetheless, we’ve covered the basics and are starting to unlock the true potential of learning SASS.

Diving Deeper

There’s quite a bit more you can do with extends and especially mixins. Some of this you may have to find on your own since there are many small utilities SASS provides. It would be hard to cover them all! However, I will dive into some more essential features and show you how to really use these tools. I hope to see you in the next part of this series where we dive even deeper into these wonderful SASS features.

Read Part 5: Diving Deeper into Extends and Mixins

Comments