When I first heard about Sass and other CSS preprocessors, my exact thoughts weren’t quite enthusiastic. “Why do we need another tool for something that already works as beautifully as CSS?”. “I won’t use that”. “My CSS is ordered enough to not need it”. “A preprocessor is for people who don’t know how to write CSS, if you know how to write CSS you won’t need a preprocessor”. “After all, processors are for people who do not know how to write CSS. If they did, they wouldn’t need need a preprocessor”. And I actually avoided them for a while, until I was forced to use it in several projects.
Embrace Sass once, and you may never want to go back to vanilla CSS again
I didn’t realise how much I was enjoying working with Sass until recently, when I had to switch back to vanilla CSS in a project. During that time, I learned so much that I decided to praise Sass and make this a better world, and make you a happier person!
Why Use Sass Anyway?
Organization: @import
This project that I just mentioned, a large e-commerce website, had a single CSS file with 7184 lines of uncompressed style declarations. Yes, you read it right: seven thousand one hundred and eighty four lines of CSS. I am sure this is not the biggest CSS file front-end developers had to handle in the industry, but it was big enough to be a complete mess.
This is the first reason why you need Sass: it helps you organize and modularize your stylesheets. It’s not variables, it’s not nesting. For me the key feature of Sass are partials and how it extends the CSS @import rule to allow it to import SCSS and Sass files. In practice, this means that you will be able to split your huge style.css file into several smaller files that will be easier to maintain, understand, and organize.
Sass helps you organize and modularize your stylesheets
The @import rule has been around for almost as long as CSS itself. However, it gained bad fame since when you use @import in your CSS files, you trigger separate HTTP requests, one for each CSS file that you are importing. This can be detrimental to the performance of your site. So what happens what you use it with Sass? If you never stopped to think about what the word “preprocessor” means, now is the time.
“A preprocessor is a program that processes its input data to produce output that is used as input to another program.” —Wikipedia
So, going back to our @import rule, this means that the @import will be handled by Sass and all our CSS and SCSS files will be compiled to a single file that will end up in our live site. The user will have to make only one request and will download a single file, while your project structure can be comprised of hundreds of modularized files. This is what the style.scss of a typical Sass project may look like:
@import “variables”;
@import “reset”;
@import “fonts”;
@import “base”;
@import “buttons”;
@import “layout”;
Don’t Repeat Yourself: Variables
Any article praising Sass will probably start by mentioning its star feature - variables. The most common use of variables is a color palette. How many times did you find several declarations of what is supposed to be the same color, ending up in the CSS as slightly different shades because nobody uses the same hex code? Sass to the rescue. In Sass, you can declare variables with almost any value. So, our color palette can be something like:
$brand: #226666;
$secondary: #403075;
$emphasis: #AA8439;
The words starting with “$” are Sass variables. What it means is that later in your stylesheets, you will be able to use those words, and they will be mapped to the values that you defined before:
body {
background: $secondary;
}
.logo {
color: $brand;
}
a {
color: $emphasis;
}
a:hover {
color: $brand;
}
Imagine how this could change our 7184 lines of CSS code, and you may start desiring Sass right now. Even better, imagine there is a redesign of the brand and you need to update all the colors in your CSS. With Sass, the only thing you need to do is to update the declarations of those variables once, and baam! The changes will be all around your stylesheets.
I coded this example in Sassmeister, a Sass playground. So go ahead and try changing those variables to something else.
The usefulness of variables are not just limited to colors, but font declarations, sizes, media queries, and more. This is a really basic example to give you an idea, but believe me, the possibilities with Sass are endless.
The possibilities with Sass are endless
Cleaner Source Code: Nesting
Nesting could be possibly the second most mentioned feature of Sass. When I went back to vanilla CSS after using Sass, the CSS file I was looking at seemed so cluttered that I wasn’t sure if it was minified. Without nesting, vanilla CSS doesn’t look any better than pretty printed .min.css files:
.header {
margin: 0;
padding: 1em;
border-bottom: 1px solid #CCC;
}
.header.is-fixed {
position: fixed;
top: 0;
right: 0;
left: 0;
}
.header .nav {
list-style: none;
}
.header .nav li {
display: inline-block;
}
.header .nav li a {
display: block;
padding: 0.5em;
color: #AA8439;
}
With Nesting, you can add classes between the braces of a declaration. Sass will compile and handle the selectors quite intuitively. You can even use the “&” character to get a reference of the parent selector. Going back to our example CSS, we can transform it to:
.header {
margin: 0;
padding: 1em;
border-bottom: 1px solid #CCC;
&.is-fixed {
position: fixed;
top: 0;
right: 0;
left: 0;
}
.nav {
list-style: none;
li {
display: inline-block;
a {
display: block;
padding: 0.5em;
color: #AA8439;
}
}
}
}
It looks beautiful and is easier to read. Feel free to play with this example.
Again! Don’t Repeat Yourself: Mixins and Extends
Repetition in CSS is always hard to avoid. And it doesn’t hurt to stress on this a bit more, especially when Sass gives you mixins and extends. They are both powerful features and help avoid a lot of repetition. Possibilities with mixins and extends don’t seem to have an end. With mixins, you can make parameterized CSS declarations and reuse them throughout your stylesheets.
Keep things DRY with Sass
For example, let’s say you have a box module with a button inside. You want the border of the box and the background of the button to be of the same color. With vanilla CSS, you do something like:
.box {
border: 2px solid red;
}
.box .button {
background: red;
}
Let’s say you now want the same box module, but with a different color. You will add something like this to your CSS:
.box-alt {
border: 2px solid blue;
}
.box-alt .button {
background: blue;
}
Now, let’s say you want a box module, but with thinner border. You would add:
.box-slim {
border: 1px solid red;
}
.box-slim .button {
background: red;
}
A lot of repetition, right? With Sass you can abstract these cases to reduce repetition. You could define a mixin like this one:
@mixin box($borderSize, $color) {
border: $borderSize solid $color;
.button {
background: $color;
}
}
And so, your source code can be reduced to:
.box { @include box(2px, red); }
.box-alt { @include box(2px, blue); }
.box-slim { @include box(1px, red); }
Looks beautiful, right? Play around with this example. You can create your own library of mixins, or even better you can use one of the community libraries out there.
Extends are similar, they let you share properties from one selector to another. However, instead of outputting multiple declarations, they output a list of classes without repeating your properties. This way you can avoid repetition of code in your output as well. Let’s forget about the buttons in our previous example and see how @extend would work with .boxes.
Let’s say you declare a first box:
.box {
margin: 1em;
padding: 1em;
border: 2px solid red;
}
Now you want two boxes similar to this one, but with different border colors. You can do something like:
.box-blue {
@extend .box;
border-color: blue;
}
.box-red {
@extend .box;
border-color: red;
}
This is how the compiled CSS would look like:
.box, .box-blue, .box-red {
margin: 1em;
padding: 1em;
border: 2px solid red;
}
.box-blue {
border-color: blue;
}
.box-red {
border-color: red;
}
Powerful, right? You can find the example here. If you review the resulting CSS, you will realize that the class .box is being included in the output. If you don’t want this behavior, you can combine @extend with “placeholders”. A placeholder is a special selector that won’t output a class in the CSS. For example, I sometimes find myself resetting the default styles of lists a lot. I generally use @extend with a placeholder like this:
%unstyled-list {
list-style: none;
margin: 0;
padding: 0;
}
You can then reuse this pattern in all your stylesheets:
.search-results {
@extend %unstyled-list;
}
.posts {
@extend %unstyled-list;
}
.nav {
@extend %unstyled-list;
}
Your compiled CSS will look like:
.search-results, .posts, .nav {
list-style: none;
margin: 0;
padding: 0;
}
Check out the examples here.
Is There More?
Absolutely! I didn’t want to overcomplicate this article, but there is a Sassy world waiting to be discovered by you; and there are also a lot of features beyond those: operations, single-line comments with //, functions, if loops … if you ever thought “it would be great to do some ‘X’ thing with CSS”, I’m sure that thing ‘X’ is already done by Sass. “CSS with superpowers” is its tagline, and that can’t be any closer to the truth.
Conclusion
Go and visit the install page and start hacking! Believe me, you won’t regret it.
Yes, there are some alternatives to Sass. Other preprocessors (LESS, Stylus), postprocessors, Grunt, etc. There are even CSS Variables. I’m not saying that Sass is the only technology out there. All I’m saying is that it’s the best! At least for now. Don’t believe in what I’m saying? Go ahead and try it yourself. You won’t regret it!