Write maintainable CSS with SASS

I recently started using the SASS framework for any front-end development work that I do. The trigger came from a ever-going frustration about trying to write maintainable CSS code. Now I wish that I had discovered SASS earlier. I’m even so positive about it that I wrote this article to share my experiences.

Frustration

Everyone who has worked on the front-end of a web project of a decent size has encountered the limitations of CSS. Not limitations in terms of what you can express (that used to be a big problem too but not so much anymore with CSS2 and CSS3) but in terms of maintainability of your code. With every front-end project I started I had good intentions from the beginning; this was going to be the project where the stylesheets will be well organized, duplication will be minimized and reusable classes will be maximized, making it easy to read for myself and others, and easy to modify. Overall, this project will have maintainable stylesheets. Every single time however, it turned out to be a deception. After every round of modifications, the stylesheets got more and more messy. This despite paying particular attention to the good practices of writing CSS that I learned by experience. After being disappointed in this way project after project, I had to conclude that the nature of the language itself make it impossible to write maintainable CSS.

The assembly of the web

In my opinion, CSS is a bit like assembly. Okay, the analogy does not entirely hold because CSS is not really a programming language, but you get the idea. CSS is the language that the browser understands just like assembly is the language that your processor understands (not entirely true but the step from assembly to binary is almost trivial). But almost nobody writes assembly anymore because it lacks abstractions that make it easy for us humans to write, maintain and understand code. In the same way, we shouldn’t be writing CSS but instead write our stylesheets in a higher-level language. Meet SASS. So far I have used it for two projects and I’m extremely positive about it. As their web page says, SASS makes CSS fun again.

Syntactically Awesome Stylesheets

SASS is an extension of CSS3 that adds a couple of nice features to the language. The way it works is that you write your stylesheets in a language called SCSS which then get compiled by the SASS preprocessor into CSS. The compilation step happens while you’re developing so there’s no performance hit on either server- or client-side. To get an idea of the features that are defined in the SCCS language, I recommend you to go over the very nice introductory tutorial. For me, its main features basically come down to this:

Nesting

Imagine you have a separate CSS file for a “Search Results” page. You want to prevent the styles defined in this page to affect the other pages so you wrap the page in a <div class="search-results-page"></div> container and you prepend every CSS rule with this class. So your CSS file looks like

.search-results-page header {...}
.search-results-page header h1 {...}
.search-results-page .content p {...}
.... and so on ...

Now, imagine that you have good reasons to change the name of the page to “Search Page” and to stay consistent, you therefore also want to change the class name of the outer container to search-page. A quick search-replace might do the job, but that’s not very elegant is it? The problem is that CSS only allows a flat hierarchy. In SASS you can define nested hierarchies, thereby mimicking the DOM tree in your stylesheets. You would do

.search-results-page {
   header {
      ...
      h1 { ... }
   }
   .content p { ... }
}

And then you only have a single replacement to do!

Variables

In SASS you can define variables that you can access throughout the stylesheets. A good design is a consistent design so often you’ll find yourself reusing the same color values, font stacks or margin and padding values. No more copy-pasting with SASS; you define the variable only once and use it everywhere.

$blue: #007cb4
a {
   color: $blue;
   ...
}

Arithmetic

In CSS you often end up with “magical” pixel values. For instance, the margin of this element is the width of this element plus 20 pixels of padding. You calculate this value once but when you read over the code some time later, it’s very hard to know where this value came from. You can add a comment but then you have an extra worry of keeping it in sync with the code.  In SASS, you can do arithmetic (the standard +, -, *, / and % operations). This way, the documentation is in the code itself!

$element-x-width: 500px
.element-y { width: $element-x-width + 20px; }

Functions

SASS also allows you to define functions. For instance, the following function converts a pixel value to an em value. In this example you can also see that it’s possible to write conditional statements.

@function em($pxval, $base: 16) {
   @if (unitless($pxval)) {
      $pxval: $pxval * 1px;
   }

   @if (unitless($base)) {
      $base: $base * 1px;
   }

   @return $pxval / $base * 1em;
}

The SASS framework has a library of predefined functions that you can use.

Mixins

Mixins are one of the most powerful features in the language. One of the ways in CSS to avoid duplication and to improve reusability is by using CSS classes. You define a class in your stylesheet once and add the class to any DOM element you want to apply the style upon. The result is that some of your DOM elements can end up with many classes attached to them. For instance, if you use the Bootstrap framework and also have a few classes of your own, you might end up with an element like the following:

<div class=”span4 offset2 primary-button container”></div>

This is okay if it wasn’t that there should be a clear separation between HTML and CSS: the former is for the content, the latter is for the presentation. This is the reason why we don’t use <font> tags anymore. However, the classes in the example clearly define the presentation of the element and that is a violation of this principle.

SASS solves this problem with mixins. Basically, they work like classes except that instead of applying them in HTML, you apply them directly in the stylesheet. In this example, it would look like:

<div class=”meaningful-name-for-this-button”></div>
@mixin span4 {
   float: left;
   width: 25%;
   ...
}
@mixin offset2 {...}
@mixin primary-button {
   display: block;
   background: red;
   ...
}
@mixin container {...}

.meaningful-name-for-button {
   @include span4;
   @include offset2;
   @include primary-button;
   @include container;
}

And now you do have a better separation between content and presentation. Mixins are also very useful for CSS properties that still require prefixed versions as well. For instance, you could define a mixin for box-sizing as follows:

@mixin box-sizing($value: content-box) {
   -moz-box-sizing: $value;
   -webkit-box-sizing: $value;
   box-sizing: $value;
}

LESS

Note that LESS is another popular stylesheet language that is very similar to SASS. However, it seems that at this moment, SASS is more powerful and robust than LESS (see a comparison and the story of someone who switched from LESS to SASS).

Using SASS in practice

Compass

The SASS framework is written in Ruby and can be installed as a Ruby Gem. However, I recommend to install Compass instead. It is also written in Ruby and it is built on top of SASS. Compass extends it with a set of useful functions and mixins. Just install the gem, create a project and execute compass watch. This program will watch any changes in your SASS files and automatically update the CSS files. This prevents you from having to manually compile to CSS after every change.

Compass comes with mixins for CSS3 properties (you don’t have to worry about prefixes anymore), helper functions (I found myself using image-width and image-height a lot) and a library to create and use sprites. The latter is very powerful: you just put the images in a sprite in the same directory and Compass does the rest for you. It creates the sprite and manages all the filenames and background positions.

Bourbon

Although Compass provides a lot of very useful mixins and functions, the Bourbon framework has a few mixins that Compass doesn’t have such as hide-text, position and size. Note that including such libraries do not add overhead to your stylesheets because a mixin only results in outputted CSS code if you actually use it. Importing a library that only defines mixins, variables and functions has no consequences for your CSS.

A mixin for better imports

The @import construct of SASS is very similar to the one in CSS. It is fairly basic in that if you import a file twice, it will also include the code twice. To solve this, this person has created a small piece of SASS code that prevents this from happening. It works in the same way as the #ifndef/#define construct in C. Define a file sass-import-once.scss with the following content.

$modules: () !default;

@mixin exports($name) {
   @if (index($modules, $name) == false) {
      $modules: append($modules, $name);
      @content;
   }
}

Then if you have a file _page.scss that you only want to include once in your project, you wrap it as follows:

@import "sass-import-once";

@include exports("page") {
   ... styles for the page ...
}

Conclusion

SASS is a huge improvement over plain CSS as it solves its biggest problem: maintainability. I’ve noticed the improvement very clearly: I spend much less time finding a certain rule that I want to modify because the stylesheets are much better organized. Also, before SASS, I often found myself not refactoring a piece of code because I knew that it would be a very error-prone process. In SASS, it’s often very doable to perform a certain refactoring, therefore maintaining a higher code quality. The difference only gets bigger as the project and the amount of code grows. I can only strongly recommend it to any front-end developer!

Write us your thoughts about this post. Be kind & Play nice.