How to write cleaner CSS and smarter SASS

Anthony DiSpezio explains how to leverage mixins and extends at the same time, to write smarter Sass and cleaner CSS.

Sass has a well-earned reputation among frontend developers for wrangling complex CSS into smart, reusable code. This is unquestionably valuable for scaling and maintenance, and allows developers to augment the shortcomings presented by traditional CSS.

Two of Sass' most fundamental features are mixins and extends. While often grouped together for their ability to generate additional styles, each offers a unique approach for solving common CSS drawbacks.

In developing Sass proficiency, knowing when to use a mixin or extend is key. But mixins and extends are by no means exclusive and, when used together, can produce cleaner, more robust markup. To better understand how these two features can work in tandem, let's start by taking a closer look at their unique behaviour.

The humble mixin

Mixins are one of the basic building blocks of Sass. Simply wrap a group of properties or selectors in a mixin, and the code can be reused by including the mixin later on.

Writing the commonly shared code once ensures that future edits can be made in a single place – a core tenant of the DRY methodology. This example button mixin contains shared border properties that are included by two different button classes:

SCSS

@mixin button {
    border-radius: 4px;
    border: 4px solid black;
}

.search-button {
    @include button;
    background-color: blue;
}

.cancel-button {
    @include button;
    background-color: red;
}

CSS

.search-button {
    border-radius: 4px;
    border: 4px solid black;
    background-color: blue;
}

.cancel-button {
    border-radius: 4px;
    border: 4px solid black;
    background-color: red;
}

Include the mixin with the values for each argument to generate unique CSS for each class:

SCSS

@include button('search', blue);
@include button('cancel', red);

CSS

.search-button {
    background-color: blue;
    border-radius: 4px;
    border: 4px solid black;
}
.cancel-button {
    background-color: red;
    border-radius: 4px;
    border: 4px solid black;
}

Even in this small example it's easy to see the scalable power of Sass.

Downsides and duplication

Although it is a straightforward process to use mixins to repeat blocks of CSS, it's not always the smartest thing to do. The CSS output generated by the mixin now contains two classes, each with identical border properties.

Constantly using mixins in this manner will generate less-than-optimal markup and a bloated CSS output full of duplicate code. Luckily, we can use extend to pick up where the mixin leaves off.

Drying our with Extend

The extend feature allows classes to inherit all of the properties of another class by grouping the selectors together. Instead of duplicating the CSS each time like a mixin, the selector is grouped with the class it extended:

SCSS

.button {
    border-radius: 4px;
    border: 4px solid black;
}

.search-button {
    @extend .button;
    background: blue;
}

CSS

.button,
.search-button {
    border-radius: 4px;
    border: 4px solid black;
}

.search-button {
    background: blue;
}

Now our output only has one instance of the border properties shared by our buttons. We can utilise this convention to streamline the mixin's output.

So happy together

The mixin-only approach was bloated because every time we called the mixin, we unnecessarily duplicated the border properties. Instead of writing these shared properties directly in the mixin, we can extend an existing class that contains them, reducing the amount of duplicate code:

SCSS

.button {
    border-radius: 4px;
    border: 4px solid black;
}

@mixin button($name, $background-color) {
    .#{$name}-button {
        background-color: $background-color;
        @extend .button;
    }
}

@include button('search', blue);
@include button('cancel', red);

The classes that inherit the shared button properties have been grouped with the .button class, eliminating the duplicate border properties.

CSS

.buton, .search-button, .cancel-button {
    border-radius: 4px;
    border: 4px solid black; 
}

.search-button {
    background-color: blue; 
}

.cancel-button {
    background-color: red;
}

This mixin/extend combo can be used to generate many buttons while reducing the amount of duplicate CSS.

More advanced Sass features, such as placeholder selectors, can help to further increase the cleanliness of this code.

Finding a balance

Intelligent use of mixins and extends has led to some remarkable Sass modules, but remember to always check the CSS output. Sass is not a panacea for every CSS issue, and will require some finesse to achieve the expected output.

Experiment with different techniques and see how these features can be woven together to create powerful mixins and clean stylesheets. Sass' active community means there are always new ideas to explore, discover and contribute.

Have fun!

Words: Anthony Dispezio

Anthony Dispezio is a content engineer and expert in HTML, CSS, Sass, JavaScript, WordPress and the N64. Follow him on Twitter at @adsipezio. This article appeared first in issue 261 of net magazine.

Like this? Read this!

Topics