Why You Should Embrace Sass and Move Away from Vanilla CSS

Upon first encountering Sass and its CSS preprocessor brethren, my reaction was far from enthusiastic. “Why fix what ain’t broke?” I thought. “CSS works perfectly fine as is. My code is organized enough, I don’t need another tool. Preprocessors are for those who can’t write proper CSS.” I stubbornly resisted, until several projects forced my hand.

Embrace Sass once, and you may never want to go back to vanilla CSS again
Embrace Sass once, and you may never want to go back to vanilla CSS again

It wasn’t until I had to revert to vanilla CSS for a project that I realized how much I’d come to appreciate Sass. That experience was so enlightening that I felt compelled to sing Sass’s praises to the world and share its joy.

Why Sass?

Organization: @import

This particular project, a large e-commerce site, had a single CSS file containing a monstrous 7,184 lines of uncompressed style declarations. It might not be the largest CSS file out there, but it was a chaotic mess.

Here’s where Sass shines: it brings order and modularity to your stylesheets. Not just with variables or nesting, but primarily with partials and its enhanced @import rule that allows importing SCSS and Sass files. This means you can break down that behemoth style.css file into smaller, manageable, and well-organized chunks.

Sass helps you organize and modularize your stylesheets
Sass helps you organize and modularize your stylesheets

While the @import rule has been around since CSS’s early days, it earned a bad rap for triggering separate HTTP requests for each imported file, potentially impacting website performance. But here’s where the “preprocessor” in Sass comes into play.

A preprocessor processes input data to produce output that another program can use. —Wikipedia

Applied to the @import rule, it means Sass handles the imports, compiling all your CSS and SCSS files into a single file for your live site. Users make a single request and download a single file, while your project benefits from a structured hierarchy of modularized files. A typical Sass project’s style.scss might look something like this:

1
2
3
4
5
6
@import “variables”;
@import “reset”;
@import “fonts”;
@import “base”;
@import “buttons”;
@import “layout”;

Don’t Repeat Yourself: Variables

No praise for Sass is complete without mentioning its star feature—variables. Their most common use is in defining color palettes. How many times have you encountered slightly different shades of the same color in your CSS because no one used the same hex code? Sass to the rescue! In Sass, you can declare variables for almost any value, including your color palette:

1
2
3
$brand: #226666;
$secondary: #403075;
$emphasis: #AA8439;

The words prefixed with “$” are Sass variables. These can be used throughout your stylesheets and will be replaced with their defined values:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
body {
  background: $secondary;
}

.logo {
  color: $brand;
}

a {
  color: $emphasis;
}

a:hover {
  color: $brand;
}

Imagine the impact this could have on our 7,184 lines of CSS code. Better yet, imagine a brand redesign requiring you to update all the colors. With Sass, you only need to update the variable declarations once, and voilà—the changes ripple through your stylesheets.

I’ve created this example in Sassmeister—a Sass playground where you can experiment with changing these variables.

The power of variables extends beyond colors to font declarations, sizes, media queries, and more. This is just a taste of what’s possible with Sass.

The possibilities with Sass are endless

Cleaner Source Code: Nesting

Nesting is another frequently lauded feature of Sass. After using Sass, vanilla CSS without nesting can feel like a jumbled mess, almost indistinguishable from a minified file.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
.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;
}

Nesting allows you to nest classes within a declaration’s braces. Sass intelligently compiles and handles the selectors. You can even use the “&” character to reference the parent selector. Our example CSS transforms into this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
.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;
      }
      
    }

  }

}

Much cleaner and easier to read. Feel free to experiment with this example.

Again! Don’t Repeat Yourself: Mixins and Extends

Repetition is a constant challenge in CSS, and Sass addresses this with mixins and extends. These powerful features help minimize repetition and offer endless possibilities.

Keep things DRY with Sass
Keep things DRY with Sass

Let’s say you have a box module with a button, and you want the box border and button background to have the same color. In vanilla CSS, you’d do something like:

1
2
3
4
5
6
7
.box {
  border: 2px solid red;
}

.box .button {
  background: red;
}

If you need the same module but with a different color, you’d add:

1
2
3
4
5
6
7
.box-alt {
  border: 2px solid blue;
}

.box-alt .button {
  background: blue;
}

And for a module with a thinner border:

1
2
3
4
5
6
7
.box-slim {
  border: 1px solid red;
}

.box-slim .button {
  background: red;
}

Quite repetitive, right? Sass allows you to abstract these cases to reduce redundancy. You could define a mixin like this:

1
2
3
4
5
6
7
8
9
@mixin box($borderSize, $color) {

  border: $borderSize solid $color;

  .button {
    background: $color;
  }

}

And your source code becomes:

1
2
3
.box { @include box(2px, red); }
.box-alt { @include box(2px, blue); }
.box-slim { @include box(1px, red); }

Much cleaner! Play around with this example. You can create your own library of mixins or leverage existing community libraries.

Extends are similar, enabling you to share properties between selectors. However, instead of outputting multiple declarations, they output a list of classes without repeating properties, minimizing repetition in the output. Let’s focus on the boxes from the previous example and see how @extend works.

Let’s say you have a basic box:

1
2
3
4
5
.box {
  margin: 1em;
  padding: 1em;  
  border: 2px solid red;
}

Now you want two similar boxes with different border colors. You can do this:

1
2
3
4
5
6
7
8
9
.box-blue {
  @extend .box;
  border-color: blue;
}

.box-red {
  @extend .box;
  border-color: red;
}

The compiled CSS would look like this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
.box, .box-blue, .box-red {
  margin: 1em;
  padding: 1em;
  border: 2px solid red;
}

.box-blue {
  border-color: blue;
}

.box-red {
  border-color: red;
}

Powerful, isn’t it? Check out the example here. Notice that the class .box is included in the output. To avoid this, combine @extend with “placeholders”—special selectors that don’t output a class. For instance, I often use @extend with a placeholder to reset list styles:

1
2
3
4
5
%unstyled-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

And then reuse this pattern throughout my stylesheets:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
.search-results {
  @extend %unstyled-list;
}

.posts {
  @extend %unstyled-list;
}

.nav {
  @extend %unstyled-list;
}

The compiled CSS:

1
2
3
4
5
.search-results, .posts, .nav {
  list-style: none;
  margin: 0;
  padding: 0;
}

See the examples here.

Is There More?

Absolutely! This is just the tip of the Sass iceberg. There’s a whole world of features to discover, including operations, single-line comments with //, functions, if loops… Whatever “it would be great if CSS could do X” thought you’ve had, Sass likely already has a solution. It’s “CSS with superpowers,” as its tagline rightfully claims.

Conclusion

Head over to the install page and start exploring! You won’t regret it.

Yes, alternatives to Sass exist, like LESS, Stylus, postprocessors, Grunt, and even CSS Variables. I’m not saying Sass is the only solution, but I believe it’s currently the best. Don’t take my word for it—try it yourself. You won’t be disappointed.

Licensed under CC BY-NC-SA 4.0