Sass vs. LESS vs. Stylus: Preprocessor Shootout

Wielding the true power of a CSS preprocessor is an adventure. There are countless languages, syntaxes, and features, all ready for use right now.

In this article, we will be covering the various features and benefits of using three different preprocessors—Sass, LESS, and Stylus.


Introduction

Preprocessors produce CSS that works in all browsers.

CSS3 preprocessors are languages written for the sole purpose of adding cool, inventive features to CSS without breaking browser compatibility. They do this by compiling the code we write into regular CSS that can be used in any browser all the way back to the stone ages. There are thousands of features that preprocessors bring to the table, and in this article we will cover some of the publicized ones, and some of the not-so-publicized ones. Let's get started.


Syntax

The most important part of writing code in a CSS preprocessor is understanding the syntax. Luckily for us, the syntax is (or can be) identical to regular CSS for all three preprocessors.

Sass & LESS

Sass and LESS both use the standard CSS syntax. This makes it extremely easy to convert an existing CSS file to either preprocessor. Sass uses the .scss file extension and LESS uses the .less extension. The basic Sass or LESS file can be setup like below:

As you may have noticed, this is just regular CSS, which compiles perfectly in both Sass and LESS.

It's important to note that Sass also has an older syntax, which omits semicolons and curly brackets. Although this is still around, it is old and we won't be using it past this example. The syntax uses the .sass file extension and looks like this:

Stylus

The syntax for Stylus is much more verbose. Using the .styl file extension, Stylus accepts the standard CSS syntax, but it also accepts some other variations where brackets, colons, and semi-colons are all optional. For example:

Using different variations in the same stylesheet is also valid, so the following will compile without errors.


Variables

Variables can be declared and used throughout the stylesheet. They can have any value that is a CSS value (e.g. colors, numbers [units included], or text.), and can be referenced anywhere throughout our stylesheet.

Sass

Sass variables are prepended with the $ symbol and the value and name are separated with a semicolon, just like a CSS property.

LESS

LESS variables are exactly the same as Sass variables, except the variable names are prepended with the @ symbol.

Stylus

Stylus variables don't require anything to be prepended to them, although it allows the $ symbol. As always, the ending semicolon is not required, but an equal sign in between the value and variable is. One thing to note is that Stylus (0.22.4) compiles if we prepend the @ symbol to a variable name, but will not apply the value when referenced. In other words, don't do that.

Compiled CSS

Each of the above files will compile to the same CSS. You can use your imagination to see how useful variables can be. We will no longer need to change one color and have to retype it twenty times, or want to change our site width and have to dig around to find it. Here's the CSS after compilation:


Nesting

If we need to reference multiple elements with the same parent in our CSS, it can be tedious to keep writing the parent over and over.

Instead, using a preprocessor, we can write the children selectors inside the parent's brackets. Also, the & symbol references the parent selector.

Sass, LESS, & Stylus

All three preprocessors have the same syntax for nesting selectors.

Compiled CSS

This is the compiled CSS from the code above. It is exactly the same as when we started—how convenient!


Mixins

Mixins are functions that allow the reuse of properties throughout our stylesheet. Rather than having to go throughout our stylesheet and change a property multiple times, we can now just change it inside our mixin. This can be really useful for specific styling of elements and vendor prefixes. When mixins are called from within a CSS selector, the mixin arguments are recognized and the styles inside the mixin are applied to the selector.

Sass

LESS

Stylus

Compiled CSS

All the preprocessors compile to the same code below:


Inheritance

When writing CSS the old-fashioned way, we could use the following code to apply the same styles to multiple elements at once:

That works great, but if we need to further style the elements individually, another selector has to be created for each and it can quickly get messier and harder to maintain. To counter this, inheritance can be used. Inheritance is the ability for other CSS selectors to inherit the properties of another selector.

Sass & Stylus

Compiled CSS (Sass & Stylus)

LESS

LESS doesn't truly support inheriting styles like Sass and Stylus. Instead of adding multiple selectors to one set of properties, it treats inheritance like a mixin without arguments and imports the styles into their own selectors. The downside to this is that the properties are repeated in your compiled stylesheet. Here's how you would set it up:

Compiled CSS (LESS)

As you can see, the styles from .block were inserted into the selectors that we wanted to give the inheritance to. It's important to note that priority can become an issue here, so be cautious.


Importing

In the CSS community, importing CSS is frowned upon because it requires multiple HTTP requests. Importing with a preprocessor works differently, however. If you import a file from any of the three preprocessors, it will literally include the import during the compile, creating only one file. Keep in mind though that importing regular .css files compiles with the default @import "file.css"; code. Also, mixins and variables can be imported and used in your main stylesheet. Importation makes creating separate files for organization very worthwhile.

Sass, LESS, & Stylus

Compiled CSS


Color Functions

Color functions are built in functions that will transform a color upon compilation. This can be extremely useful for creating gradients, darker hover colors, and much more.

Sass

This is only a short list of the available color functions in Sass, a full list of available Sass color functions can be found by reading the Sass Documentation.

Color functions can be used anywhere that a color is valid CSS. Here's an example:

LESS

A list of all the LESS functions can be found by reading the LESS Documentation.

Here's an example of how to use a color function in LESS:

Stylus

A full list of all the Stylus color functions can be found by reading the Stylus Documentation.

Here's an example using Stylus color functions:


Operations

Doing math in CSS is quite useful, and now fully possible. It's simple and this is how to do it:

Sass, LESS, & Stylus


Practical Applications

We have covered a lot of the features and new things that preprocessors can do, but we haven't covered anything hands-on or practical. Here's a short list of real-world applications where using a preprocessor is a life-saver.

Vendor Prefixes

This is one of the hyped up reasons to use a preprocessor and for a very good reason—it saves loads of time and tears. Creating a mixin to handle vendor prefixes is easy and saves a lot of repetition and painful editing. Here's how to do it:

Sass

LESS

Stylus

Compiled CSS

3D Text

Faking 3D text using multiple text-shadows is a clever idea. The only problem is that changing the color after the fact is difficult and cumbersome. Using mixins and color functions, we can create 3D text and change the color on the fly!

Sass

LESS

Stylus

I chose to write the Stylus text-shadows on one line because I omitted the curly brackets.

Compiled CSS

End Result

Columns

Using number operations and variables for columns is an idea I came up with when I was first playing with CSS preprocessors. By declaring a desired width in a variable, we can easily change it down the road without any mental-math. Here's how it's done:

Sass

LESS

Stylus

Compiled CSS


Notable Quirks

There are quite a few quirks to using a CSS preprocessor. I'm going to go over a few of the fun ones, but if you're really interested in finding them all I recommend you scour the documentation or, better yet, just start using a preprocessor in your daily coding.

Error Reporting

If you've written CSS for any decent amount of time, I am sure you have reached a point where you had an error somewhere and simply could not find it. If you're anything like me you probably spent the afternoon pulling your hair out and commenting out various things to hunt the error down.

CSS preprocessors report errors. It's just that simple. If there's something wrong with your code it tells you where, and if you're lucky: why. You can check out this blog post if you're interested in seeing how errors are reported in the different preprocessors.

Comments

When compiling with a CSS preprocessor, any double-slash comment gets removed (e.g. //comment) and any slash-asterisk comment stays (e.g. /* comment */). That being said, use double-slash for comments you want on the non-compiled side and slash-asterisk for comments you want visible after the compilation.

Just a note: if you compile minified, all comments are removed.


Conclusion

Each CSS preprocessor we covered (Sass, LESS, and Stylus) has its own unique way of accomplishing the same task— giving developers the ability to use useful, unsupported features while keeping browser compatibility and code cleanliness.

While not a requirement for development, preprocessors can save a lot of time and have some very useful features.

I encourage you all to try as many of the preprocessors as possible so that you can effectively choose a favorite and know why it is favored over the numerous others. If you haven't yet tried using a preprocessor to write your CSS, I highly recommend you give it a try.

Do you have a favorite CSS preprocessor feature I didn't mention? Is there something one can do that another cannot? Let us know in the comments below!

A special thanks to Karissa Smith, a super-talented friend of mine that created the preview thumbnail for this article.

Tags:

Comments

Related Articles