Sass: An Introduction for Beginners

30 April 2024

Sass, the CSS preprocessor

You’re developing a site or web app, or a new feature for an existing one. You’ve done all the backend work and everything’s in the right place, except that it looks horrible. Time for some CSS… right?

Cascading Style Sheets have been around for a while now. Since 1996, to be precise, which makes CSS older than me. And it’s not just that it’s old – it can be clunky and messy, too. Let’s say I have a div with the class my-container. It contains a heading and some paragraphs. I’d like a bold heading and I’d like my paragraphs to have blue text, but only in this div – not anywhere else on the page. With CSS, I’d have to do something like this:

.my-container h1 {
    font-weight: bold;
}

.my-container p {
    color: blue;
}

Since December 2023, CSS has actually supported nesting. However, with global browser support still below 90%, using this feature might not be the best choice right now. What if there was some sort of workaround? What if I could simply write something along these lines:

.my-container {
    h1 {
        font-weight: bold;
    }

    p {
        color: blue;
    }
}

If I wanted to change that my-container class name for some reason, I’d only have one place to change it in the CSS, not two. And this is just a simple example. CSS for a real webpage gets far, far more complicated than this.

Alas, as I mentioned before, nesting in CSS is new and the browser support just isn’t quite there yet.

It turns out, however, that there is a workaround.

Enter Syntactically Awesome Style Sheets, or Sass for short. It’s a CSS preprocessor, which means it gets compiled to CSS (without any nesting) before it’s served. With the exception of the new native CSS nesting, it’s also a superset of CSS, which means that all valid CSS (as long as it doesn’t use nesting) is also valid SCSS (but not vice-versa).

That last code example is valid Sass. More specifically, it’s valid SCSS (Sassy CSS): the newer Sass syntax and successor of the older SassScript. Nesting isn’t where it ends, though; far from it. Sass has plenty of other nice syntactic features. Here are some brief summaries of my favourites…

Mixins

Let’s say, for example, that you want all your h2 elements to be bright red on mobile for some reason. In CSS, you could do something like this:

@media screen and (max-width: 768px) {
    h2 {
        color: red;
    }
}

Not too long-winded. But say you want to reuse this media query. You’d have to type it out in full again and again. Sure, CSS does support variables (technically called custom properties), which might help with the 768px, but that’s still a little cumbersome.

Enter mixins. With Sass, we can declare a mixin like this:

@mixin mobile-only {
    @media screen and (max-width: 768px) {
        @content;
    }
}

And use it in our red h2 scenario like this:

@include mobile-only {
    h2 {
        color: red;
    }
}

Neat, isn’t it? And we can reuse that mixin throughout our code. If we ever wanted to alter that 768px width threshold, we’d only have to do so in one place.

Imports

Ever had the pleasure of dealing with a CSS file several hundred lines long? It’s not fun. Fortunately, Sass provides an escape from this: it allows you to split your styling between as many files as you like.

‘But CSS lets you do imports too!’ I hear you say. And you’re absolutely right; it does. However, there’s a crucial difference. When a web browser sees an import in a CSS file, it has to go and make another HTTP request for the imported file. I’ll leave you to deduce the performance implications of this.

SCSS code, on the other hand, is not served directly to your site’s visitors; it’s compiled to CSS before being served. An SCSS import statement is simply a directive for the compiler. It says, ‘grab the SCSS in this file and stick it in the compiled CSS’. Compilation only happens once; it’s the single compiled CSS file that your site serves to visitors. No matter how many imports you use, the browser only has to handle one CSS file. You get to keep the convenience of splitting your code across multiple files with zero performance impact.

There’s a slight syntax difference between CSS imports and SCSS imports, too. Here’s an import statement in CSS:

@import “_imported_file.css”;

Notice how you use the full filename; the above code imports the file _imported_file.css. Here’s the SCSS equivalent, where we import a file called _imported_file.scss:

@import “imported_file”;

Now you know why I put an underscore at the start of my example file name. In SCSS, the names of all imported files must begin with an underscore. When they’re imported, this preceding underscore plus the .scss file extension are omitted.

The & Operator

This is a very handy little syntax feature. Suppose I want to make all my h2 headings bold, but I only want to make the ones with the .special-heading class yellow. In CSS, I’d do something like this:

h2 {
    font-weight: bold;
}

h2.special-heading {
    color: yellow;
}

I’ve got to specify that h2 tag twice. Now look at the SCSS version.

h2 {
    font-weight: bold;

    &.special-heading {
        color: yellow;
    }
}

I’ve used the & operator. That inner block will match any h2 element with the special-heading class. Very useful when you don’t want to repeat yourself. Extremely useful for things like button hover styling. And if I decided I wanted to apply the styling to h3 tags instead of h2 tags in my example above, I’d only have to change the code in one place.

More Features

Those are my favourite features of Sass, but it certainly doesn’t end there. Variables are supported, too; you can define and use them like this:

$color__background_primary: #124356;

body {
    background-color: $color__background_primary;
}

They’re similar to CSS custom properties (which are also informally known as variables), but with some differences. For a start, you can do proper maths with them that goes far beyond the restraints of CSS’s calc() function. You can do interpolation between values, too. I won’t expand any more on it here, as it’s a topic that frankly warrants its own entire blog post. This excellent article by Sergey Gultyayev goes into far more detail.

Further to this, you can define your own functions and use inheritance, which can be very powerful if you know how to exploit it. There are also control directives like if and else, and you can even use loops.

Drawbacks of Sass

So far, I’ve been touting all the benefits of Sass without mentioning a single weakness. In my eyes, it’s certainly an improvement over CSS; it just adds so many features that streamline the styling process. This may soon change as browser support for nesting in native CSS increases, but for now, I think Sass retains the edge. Further to this, even when browser support for CSS nesting is high enough to warrant its use, all the other advantages of Sass over CSS I’ve mentioned in this article will hold.

There is of course the minor disadvantage that all languages and frameworks share of being ‘yet another thing to learn’ in a web development landscape overflowing with a myriad of different technologies. Apart from that, I can only really see one advantage that CSS has over Sass: the aforementioned CSS custom properties. They’re actually newer than SCSS variables, browser support becoming universal in 2017, and pack in some fairly powerful features. I’ll again refer you to Sergey Gultyayev’s article for more information.

That said, it’s perfectly possible to use CSS custom properties in your SCSS and combine them with all of Sass’s other useful features.

Alternatives to Sass

Sass isn’t the only preprocessor styling language; there are others, such as Less and PostCSS. Perhaps I’ll delve into them in a future article, but they lie outside the scope of this one.

Conclusion

That wraps up my thoughts on Sass and my favourite features of the SCSS language. In summary, it’s a great way to streamline the styling process and increase the legibility and maintainability of your code. It’s one of the first things I install whenever I build a custom WordPress theme: something I do for most of the sites I design and build. You can find out more about my web development services here.

Stay tuned – in a future article, I’m planning to provide a step-by-step guide on how to install Sass in your web development project.

Leave a comment