Sass vs. LESS vs. Stylus: Preprocessor Shootout

Sass vs. LESS vs. Stylus: Preprocessor Shootout

Tutorial Details

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:

/* style.scss or style.less */
h1 {
  color: #0982C1;
}

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:

/* style.sass */
h1
  color: #0982c1

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:

/* style.styl */
h1 {
  color: #0982C1;
}

/* omit brackets */
h1
  color: #0982C1;

/* omit colons and semi-colons */
h1
  color #0982C1

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

h1 {
  color #0982c1
}
h2
  font-size: 1.2em

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.

$mainColor: #0982c1;
$siteWidth: 1024px;
$borderStyle: dotted;

body {
  color: $mainColor;
  border: 1px $borderStyle $mainColor;
  max-width: $siteWidth;
}

LESS

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

@mainColor: #0982c1;
@siteWidth: 1024px;
@borderStyle: dotted;

body {
  color: @mainColor;
  border: 1px @borderStyle @mainColor;
  max-width: @siteWidth;
}

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.

mainColor = #0982c1
siteWidth = 1024px
$borderStyle = dotted

body
  color mainColor
  border 1px $borderStyle mainColor
  max-width siteWidth

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:

body {
  color: #0982c1;
  border: 1px dotted #0982c1;
  max-width: 1024px;
}

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.

section { 
  margin: 10px;
}
section nav { 
  height: 25px;
}
section nav a { 
  color: #0982C1;
}
section nav a:hover {
  text-decoration: underline;
}

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.

section {
  margin: 10px;

  nav {
    height: 25px;

    a {
      color: #0982C1;
  
      &:hover {
        text-decoration: underline;
      }
    }
  }
}

Compiled CSS

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

section {
  margin: 10px;
}
section nav {
  height: 25px;
}
section nav a {
  color: #0982C1;
}
section nav a:hover {
  text-decoration: underline;
}

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

/* Sass mixin error with (optional) argument $borderWidth which defaults to 2px if not specified */
@mixin error($borderWidth: 2px) {
  border: $borderWidth solid #F00;
  color: #F00;
}

.generic-error {
  padding: 20px;
  margin: 4px;
  @include error(); /* Applies styles from mixin error */
}
.login-error {
  left: 12px;
  position: absolute;
  top: 20px;
  @include error(5px); /* Applies styles from mixin error with argument $borderWidth equal to 5px*/
}

LESS

/* LESS mixin error with (optional) argument @borderWidth which defaults to 2px if not specified */
.error(@borderWidth: 2px) {
  border: @borderWidth solid #F00;
  color: #F00;
}

.generic-error {
  padding: 20px;
  margin: 4px;
  .error(); /* Applies styles from mixin error */
}
.login-error {
  left: 12px;
  position: absolute;
  top: 20px;
  .error(5px); /* Applies styles from mixin error with argument @borderWidth equal to 5px */
}

Stylus

/* Stylus mixin error with (optional) argument borderWidth which defaults to 2px if not specified */
error(borderWidth= 2px) {
  border: borderWidth solid #F00;
  color: #F00;
}

.generic-error {
  padding: 20px;
  margin: 4px;
  error(); /* Applies styles from mixin error */
}
.login-error {
  left: 12px;
  position: absolute;
  top: 20px;
  error(5px); /* Applies styles from mixin error with argument borderWidth equal to 5px */
}

Compiled CSS

All the preprocessors compile to the same code below:

.generic-error {
  padding: 20px;
  margin: 4px;
  border: 2px solid #f00;
  color: #f00;
}
.login-error {
  left: 12px;
  position: absolute;
  top: 20px;
  border: 5px solid #f00;
  color: #f00;
}

Inheritance

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

p,
ul,
ol {
  /* styles here */
}

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

.block {
  margin: 10px 5px;
  padding: 2px;
}

p {
  @extend .block; /* Inherit styles from '.block' */
  border: 1px solid #EEE;
}
ul, ol {
  @extend .block; /* Inherit styles from '.block' */
  color: #333;
  text-transform: uppercase;
}

Compiled CSS (Sass & Stylus)

.block, p, ul, ol {
  margin: 10px 5px;
  padding: 2px;
}
p {
  border: 1px solid #EEE;
}
ul, ol {
  color: #333;
  text-transform: uppercase;
}

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:

.block {
  margin: 10px 5px;
  padding: 2px;
}

p {
  .block; /* Inherit styles from '.block' */
  border: 1px solid #EEE;
}
ul, ol {
  .block; /* Inherit styles from '.block' */
  color: #333;
  text-transform: uppercase;
}

Compiled CSS (LESS)

.block {
  margin: 10px 5px;
  padding: 2px;
}
p {
  margin: 10px 5px;
  padding: 2px;
  border: 1px solid #EEE;
}
ul,
ol {
  margin: 10px 5px;
  padding: 2px;
  color: #333;
  text-transform: uppercase;
}

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

/* file.{type} */
body {
  background: #EEE;
}
@import "reset.css";
@import "file.{type}";

p {
  background: #0982C1;
}

Compiled CSS

@import "reset.css";
body {
  background: #EEE;
}
p {
  background: #0982C1;
}

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

lighten($color, 10%); /* returns a color 10% lighter than $color */
darken($color, 10%);  /* returns a color 10% darker than $color */

saturate($color, 10%);   /* returns a color 10% more saturated than $color */
desaturate($color, 10%); /* returns a color 10% less saturated than $color */

grayscale($color);  /* returns grayscale of $color */
complement($color); /* returns complement color of $color */
invert($color);     /* returns inverted color of $color */

mix($color1, $color2, 50%); /* mix $color1 with $color2 with a weight of 50% */

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:

$color: #0982C1;

h1 {
  background: $color;
  border: 3px solid darken($color, 50%);
}

LESS

lighten(@color, 10%); /* returns a color 10% lighter than @color */
darken(@color, 10%);  /* returns a color 10% darker than @color */

saturate(@color, 10%);   /* returns a color 10% more saturated than @color */
desaturate(@color, 10%); /* returns a color 10% less saturated than @color */

spin(@color, 10);  /* returns a color with a 10 degree larger in hue than @color */
spin(@color, -10); /* returns a color with a 10 degree smaller hue than @color */

mix(@color1, @color2); /* return a mix of @color1 and @color2 */

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:

@color: #0982C1;

h1 {
  background: @color;
  border: 3px solid darken(@color, 50%);
}

Stylus

lighten(color, 10%); /* returns a color 10% lighter than 'color' */
darken(color, 10%);  /* returns a color 10% darker than 'color' */

saturate(color, 10%);   /* returns a color 10% more saturated than 'color' */
desaturate(color, 10%); /* returns a color 10% less saturated than 'color' */

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:

color = #0982C1

h1
  background color
  border 3px solid darken(color, 50%)

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

body {
  margin: (14px/2);
  top: 50px + 100px;
  right: 100px - 50px;
  left: 10 * 10;
}

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

@mixin border-radius($values) {
  -webkit-border-radius: $values;
     -moz-border-radius: $values;
          border-radius: $values;
}

div {
  @include border-radius(10px);
}

LESS

.border-radius(@values) {
  -webkit-border-radius: @values;
     -moz-border-radius: @values;
          border-radius: @values;
}

div {
  .border-radius(10px);
}

Stylus

border-radius(values) {
  -webkit-border-radius: values;
     -moz-border-radius: values;
          border-radius: values;
}

div {
  border-radius(10px);
}

Compiled CSS

div {
  -webkit-border-radius: 10px;
     -moz-border-radius: 10px;
          border-radius: 10px;
}

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

@mixin text3d($color) {
  color: $color;
  text-shadow: 1px 1px 0px darken($color, 5%),
               2px 2px 0px darken($color, 10%),
               3px 3px 0px darken($color, 15%),
               4px 4px 0px darken($color, 20%),
               4px 4px 2px #000;
}

h1 {
  font-size: 32pt;
  @include text3d(#0982c1);
}

LESS

.text3d(@color) {
  color: @color;
  text-shadow: 1px 1px 0px darken(@color, 5%),
               2px 2px 0px darken(@color, 10%),
               3px 3px 0px darken(@color, 15%),
               4px 4px 0px darken(@color, 20%),
               4px 4px 2px #000;
}

span {
  font-size: 32pt;
  .text3d(#0982c1);
}

Stylus

text3d(color)
  color: color
  text-shadow: 1px 1px 0px darken(color, 5%), 2px 2px 0px darken(color, 10%), 3px 3px 0px darken(color, 15%), 4px 4px 0px darken(color, 20%), 4px 4px 2px #000
span
  font-size: 32pt
  text3d(#0982c1)

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

Compiled CSS

span {
  font-size: 32pt;
  color: #0982c1;
  text-shadow: 1px 1px 0px #097bb7, 
               2px 2px 0px #0875ae, 
               3px 3px 0px #086fa4, 
               4px 4px 0px #07689a, 
               4px 4px 2px #000;
}

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

$siteWidth: 1024px;
$gutterWidth: 20px;
$sidebarWidth: 300px;

body {
  margin: 0 auto;
  width: $siteWidth;
}
.content {
  float: left;
  width: $siteWidth - ($sidebarWidth+$gutterWidth);
}
.sidebar {
  float: left;
  margin-left: $gutterWidth;
  width: $sidebarWidth;
}

LESS

@siteWidth: 1024px;
@gutterWidth: 20px;
@sidebarWidth: 300px;

body {
  margin: 0 auto;
  width: @siteWidth;
}
.content {
  float: left;
  width: @siteWidth - (@sidebarWidth+@gutterWidth);
}
.sidebar {
  float: left;
  margin-left: @gutterWidth;
  width: @sidebarWidth;
}

Stylus

siteWidth = 1024px;
gutterWidth = 20px;
sidebarWidth = 300px;

body {
  margin: 0 auto;
  width: siteWidth;
}
.content {
  float: left;
  width: siteWidth - (sidebarWidth+gutterWidth);
}
.sidebar {
  float: left;
  margin-left: gutterWidth;
  width: sidebarWidth;
}

Compiled CSS

body {
  margin: 0 auto;
  width: 1024px;
}
.content {
  float: left;
  width: 704px;
}
.sidebar {
  float: left;
  margin-left: 20px;
  width: 300px;
}

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.

Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • http://jonathancutrell.com Jonathan

    I personally love LESS, haven’t done much else with other stuff. Tried SASS out a while ago, when it wouldn’t take straight CSS (I think it used to be indent-sensitive).

    I enjoy the concatenation and the natural sense of extension Less provides. defining clases is super simple, and then you can drop them into other elements. For instance, using less, everything defined in HTML5 boilerplate css reset becomes a mixin.

    .someClass {
    .ir;
    }
    .row {
    .clearfix;
    }

    LESS also has access to a javascript interpreter, so you can eval JS (this works great considering LESS is written in js; that’s where you get the color functions from).

    • http://elfsternberg.com Elf M. Sternberg

      Agreed on LessCSS. I especially appreciate the way it containerizes the way HTML does. I may start experimenting with Stylus, and then all of my preprocessors will be white-space sensitive (since I use HAML and Coffeescript). Some people hate it, but I appreciate the discipline and clarity it provides.

    • http://elfsternberg.com Elf M. Sternberg

      Agreed on LessCSS. I especially appreciate the way it containerizes the way HTML does. I may start experimenting with Stylus, and then all of my preprocessors will be white-space sensitive (since I use HAML and Coffeescript). Some people hate it, but I appreciate the discipline and clarity it provides.

    • http://www.hostinsight.com Hostinsight

      I started using LESS because it was the easiest to set up and it’s stuck. Code has reduced dramatically making my CSS much less overwhelming. Having to compile the CSS locally and then copy it into a separate file is a small price to pay for the hassle of setting up the other preprocessors.

  • Kieran

    One observation I’ve made is an increase in developer jobs citing LESS as a nice-to-have skill. I just noticed this as a recent trend on LinkedIn.

  • Kieran

    One observation I’ve made is an increase in developer jobs citing LESS as a nice-to-have skill. I just noticed this as a recent trend on LinkedIn.

  • Graham

    Thanks for clearing this up Jeffrey. The documentation can be a little tedious and it is always nice to have it explained in the most simple way. I am still a little confused about mix-ins though. I have dabbled a little bit with each of these, but can not seem to commit to any of them. I guess I am just trying to master vanilla css before trying to learn an easier way.

    • http://www.jeffrey-way.com Jeffrey Way

      Sorry Graham – I didn’t write this article.

  • http://highergroundstudio.com Kyle King

    One large difference you failed to hit on is that LESS is built on javascript and thus it can be run directly by including less.js which will process the LESS files on the user’s side (in the browser). This is great for development as you do not need to build the css file after changes. All you do is refresh the browser.

    We are working hard to make LESS the leader of the CSS preprocessor with it’s easy to learn syntax that is as close to CSS as possible.

    • http://twitter.com/philwareham Phil Wareham

      Letting Less compile client side via less.js is a terrible idea and one that should be discouraged IMHO. Other than that all 3 preprocessors are worthy options.

      No mention of Sass Compass then?

    • http://geek.tiboqc.com Thibaud Lescuyer

      Using SASS with Compass, you can define profiles and set it to watch your SASS file.
      That way, you can “watch” the changes using the dev profile, which will automatically compile the SASS file and put the compiled CSS into your project’s CSS folder.
      That way, all you have to do is refreshing the page, and you can use a “prod” profile which compresses the CSS and export it at the right place.

      I think they are all about the same, but the tools around may make the difference, as I think Compass makes SASS more convenient.

      And installing SASS et Compass is a really simple process.

  • http://www.stevendavisphoto.com Steven Davis

    I’ved used SASS and LESS, and love em both. Stylus seems a little too loose and sloppy for me. You should NEED the colons and semi-colons, and variable prefixes to show they are variables. I’m sure it will fit some peoples’ styles, but not mine. I prefer a bit more structure.

  • Andres Roberto Rojas

    Hi, nice tut. I don’t know too much about CSS preprocessors, but I like to try them. You have shown me the pros, but what about the cons of using preprocessor. Anyway, I am sure I will find them when I explore them. Keep doing good.

  • Pritesh Desai

    I used LESS for one project and its great, simple and easy to use. A must during development stage.
    However since it runs on the client side, I removed it once the project got complete.

  • http://www.nathanielwealth.com Nathaniel Wealth

    I am currently using SASS, but I would like to try out LESS; I do like the feature that Kyle pointed out where it can be processed dynamically via JavaScript. It would be very easy to make some crazy adaptive designs if you can have it let’s say re-process the Stylesheet on a browser resize event.

  • https://www.facebook.com/samuelmesq Samuel Mesquita

    I use less with sublime, “lessc.exe” and extension “buildOnSave,” is very good.

    • Kyle

      If you are using terminal during development, you can run:

      sass –watch _scss:_css

      and that will compile on save

  • http://brandonb.ca Brandon

    Thanks for the awesome article!

  • http://justincase.kodingen.com Justin Spradlin

    Thanks Jeffery! This is a great comparison. I will be giving a quick presentation on using LESS soon and this will be a great resource to show people.

    Thanks!

  • IncognitoChromer

    And the winner is: CSS! Because if you need preprocessors or ‘help’ to write CSS, well, you probably are just being too much of a nerd and not enough of a coder. This isn’t us trying to make a new OS using C++ or Java. This is just CSS, people. Use what works for you, be it Less, Sass, Pass, Fad, Trendzy, or whatever. I’m fine with plain CSS, from 10 lines to a million. IMO, it’s a “don’t fix what isn’t broken” sort of thing. And after 13 years of using CSS, I have no qualms with keeping it plain. I can be just as productive and efficient.

    • Drofnas

      So by that same logic I should go back to Windows 3.1 for Workgroups.

      If it isn’t broken, then it’s time to version it.

    • http://andrewensley.com/ Andrew Ensley

      Yeah… I’m confused by your reasoning. Don’t do something that will help you be productive because you can do the same thing slower?

  • http://OrganizedFellow.com OrganizedFellow

    I found several different parsers.

    Less Parser http://www.proving-ground.be/less/
    &
    SimpLESS http://wearekiss.com/simpless

    Both are multi-platform.
    Less Parser is an Adobe AIR app, so it can be used most anywhere.
    SimpLESS is available for Mac, Linus and Win.
    Both are great and work as expected.

    I prefer Less Parser as it gives the option to minify.
    It also has the added feature of separating projects.

    • Brad

      I like the Less Parser too, does a very nice job

  • http://pressedweb.com Cory

    I used to use LESS all the time until PageSpeed started noticing my selectors were 3 and 4 deep. I know it’s not the preprocessor’s fault, but after cutting back on selectors, I realized I wasn’t making a lot of use of LESS.

    I also couldn’t think of a time when I needed a mixin. What can you use them for other than color themes for the same design (something which hardly any of us ever do)? Prototyping? That seems like a job best left to Photoshop.

    I know I’m probably alone in feeling this way, but after going down the preprocessor road. I just don’t see a need for them.

    Although… double-slash comments that aren’t rendered and Stylus’ indentation-based syntax are pretty sexy. I might start using it after all, but I can almost guarantee I’ll never nest another selector.

    • http://mohsenweb.com Mohsen

      I’m with you. Computer generated code is always not optimum.

  • http://gregpettit.ca Greg

    Wow, not only a great comparison but a fantastic introduction tutorial on using any single one of the three. I still haven’t used a preprocessor, but I appreciate the possibilities. That said, part of the reason I haven’t gone that way yet is because is many (but not all) cases, a properly designed cascade will produce the same results in more efficient code.

    I think that if efficient stylesheets are the goal (and let’s face it, this isn’t always the case. Sometimes “just get the job done” is the goal) then having a firm grasp of CSS is a must. It’ll allow you to understand the right time to use variables and mixins and the right time to solve the problem with CSS natively.

    However, pretty hard to argue that nested syntax isn’t just a plus with no downside. Love it.

  • http://nataliav.me Natalia Ventre

    Sass and Stylus have more complex functions, but the documentation is definitely not written for designers.

    Less is more simple, I think the only exclusive feature are namespaces.

  • http://twitter.com/brunogama Bruno Gama

    I really have good times using less compiled with the less.app

    I want to search for a alternative to compile it at the server side with using python/django

  • taitul

    i gave less a try once. it was great but it seems like it made my site load slower.
    maybe its just my imagination.

    another point: npp syntax highlight fail when using a css preprocessor.

    how does css preprocessors effect a site’s loading time?

    • http://varemenos.com/ Varemenos

      You do realize there is a compiled .css file as well, right?

      • taitul

        of course i do.

        so its not ment for production?
        should i copy the compiled css from firebug or somthing after every change?

        is there any easy way to get the compiled css after i make changes?

        thanks

      • Lucas Rolff

        taitul, working with Less etc, doesn’t make your site slower if you use the .css file, because – it’s just regular css, which is great!

        So it should be slower actually, but take a look at the CSS that is compiled, and see if there is waay too much code, comparing to what you ‘normally’ have for same styling of a page, because yes, if it has generated a lot more CSS, it can be the way you write your less that makes it slower (because size is bigger etc.)

    • Tom

      @taitul
      I’m using eclipse for all my projects. I have defined a “custom builder” for my project, that is basically a batch file that compiles my .less on the fly.
      So whenever I change something, .less is compiled and I can refresh the WebApp/Site.
      CLI less compiler: http://bit.ly/ic4dKD.
      There is also WinLess app (same author) that monitors selected less folders and compiles them on change.

  • Tom

    I’d like to use stylus, but the environment doesn’t allow me to use node.js, and I didn’t find a good standalone (preferably commandline) compiler for windows.
    I’m using less now with an excellent cli compiler for windows (bit.ly/ic4dKD).

  • http://twitter.com/nkennedy Nate

    You can do inheritance in LESS just like SASS does. You kind of mention this above, but you don’t quite get there. Here’s an example.

    If you do this:

    .block {
    margin: 10px 5px;
    padding: 2px;
    }

    p {
    .block; /* Inherit styles from ‘.block’ */
    }

    Then .block will be displayed by itself, as a regular class, in your output CSS.

    HOWEVER, if you do this instead, the .block “class” will be hidden from the output CSS:

    .block () {
    margin: 10px 5px;
    padding: 2px;
    }
    p {
    .block; /* Inherit styles from ‘.block’ */
    }

    Notice the change? Just add an empty pair of parentheses after .block. If you do this, LESS will treat .block as a true mixin. This .block mixin happens to have default margin and padding values, and we aren’t passing any values to it.

    I do this to create all sorts of little helper “classes” with straightforward, nonsemantic names. I reuse them elsewhere in my stylesheets, but the original stuff is always hidden from the output CSS.

    • http://twitter.com/nkennedy Nate

      I’m not sure if you can edit comments here. I reread the original tutorial and misunderstood the intent.

      Still, what I described is a pretty handy little piece of tech. May be useful for some folks.

  • TJ

    @width etc in stylus references property values, which is why it’s undefined for a var, ex:

    foo {
    width: 50px
    height: @width * 2
    }

  • TJ

    also you leave out things like

    border-radius: 5px

    etc being a valid mixin

  • http://www.janskovgaard.dk Jan Skovgaard

    Very nice write-up on the different preprocessors – I’m still new to this concept and I’m currently wondering if I should start using less or sass.

    I’ve heard that sass can be used with compass, which makes it possible to generate css sprites on the fly. This is very appealing to me but I’m not that keen on the fact that I need to install a ruby based client to be able to compile the code to CSS…I would prefer just using winless, which I personally find more appealing since I’m on a windows machine and the js based watcher seems easy to get on with…

    But don’t know if compass is also possible to use with less?

  • http://www.plan-zero.org Cris

    My mayor problem with Less is working with media queries since LESS think they are part of their code I have to work with different files and import them all later which it’s not the point, everything else just work wonderful.

  • http://www.umbraprojekt.pl mingos

    LESS has been mentioned here more than once, and IIRC, I always (or nearly) mentioned the PHP compiler in the comments. Or at least I thought about it while reading the other people’s comments. Doesn’t matter. What I want to say is, if you are PHP developers, you shouldn’t even bother with the JavaScript implementation. LessPHP is compatible with it, but does all the dirty work server-side, which is both way more secure (you are guaranteed to serve a CSS file) and a heap faster! http://leafo.net/lessphp/

    • http://okeowoaderemi.com Okeowo Aderemi

      i think i like the idea of PHP handling LESS than JavaScript,

      • Rod

        Anyone heard of/used TurbineCSS? Its another PHP based preprocessor that we’ve been using for a while and I really like it, however the latest version has been sitting in beta for a while now and there doesn’t seem to be much activity happening on it, which makes me a little nervous about adopting it.

    • http://www.netd.it/sviluppo/ Netdesign (Fabio Buda)

      Lessphp is a good way to compile .less files into standard CSS.

      Anyway what we noticed is that ccompile() static function is not good at performances and including that code in all scripts (when working on big websites) would be a suicide….!

      Moreover we think that lessphp processing shouldn’t be done in scripts because of performance degradation…

      Here you can find a benchmark of ccompile() performances Vs. another way to use lesscss:
      http://www.netd.it/sviluppo/compilare-less-al-volo-con-apache-lessphp#vantaggi

      We apologize but, even if we’re going to translate it into English, at this time it is available only in Italian.

      • http://umbraprojekt.pl mingos

        You don’t need to include it in each and every script, really.

        You can run ccompile() on each request when APPLICATION_ENV=development, but run it manually (like, when cleaning the cache or something) or with cron, once every X minutes when APPLICATION_ENV=production. This lets you work comfortably on the site locally, but have it work fast when on the production server.

        I remember doing this for a pretty big community site. Cache is cleaned once every two hours there, plus each time we export a new version of the application from SVN (no changes are ever made directly on the server). So lessphp runs at the very most every two hours, and most of the time quits as soon as it checks the modification time on the source and output files (no changes to the less file). Works great for us.

      • http://www.netd.it/sviluppo/ Netdesign (Fabio Buda)

        Maybe your solution is good but it doesn’t fit our needs.

        We manage many projects and they are a “growing number”… so we decided to use mod_rewrite to compile all .less files stored in all our VirtualHosts.

        This way we can easily manage tens of projects using less withouth starting cron jobs.

        Our way to compile and “offer” less files is simple and make us able to add new projects being sure all .less file will be automatically compiled and cached.

        We need fast development lifecycle and saving time (automating some tasks) is always our first aim.

  • http://freshma.de Jack Keller

    I recently started using LESS because I heard more buzz about it and I love it. But I was a bit curious about SASS and even Stylus, I personally like the @mixin approach to SASS but the extra markup would annoy me, I get caught up in the .mixin approach to LESS a tad because it can be a tad confusing for someone less familiar if they ever need to edit one of my files down the road.

    In the long run I believe EVERYONE should begin using a Preprocessor for CSS but it’ll come down to personal preference for sure.

    Great article!

    • L.

      In the long run I believe that EVERYONE will stop using CSS preprocessors because CSS will inevitably get extended and fixed to the point where those tools that only patch some weaknesses of CSS will become irrelevant.

      Good stuff anyway, let’s drink to the future of CSS and no more -vendor- properties / vendor-only CSS fail.

  • Slpixe

    Great article.

    I have been using LESS for a few months now, and have found it great.
    was a bit disappointed to see that SASS had a few more colour features (like weight of colour mixing, and the grayscaling and inverting).

    But the thing that won me over when i was first looking at them was that LESS can use a JS compiler, and using the #!watch feature while developing locally is nice.

    was also a bit surprised when the article mentioned that inheritance isnt as well supported.

    @nate
    but thats for that fix nate, about how get the inheritance to work most efficiently.

  • http://pictode.net Mathieu

    Hi,

    A new tool could help to begin in the world of css pre-processors : http://toki-woki.net/p/least/
    It helps you to convert your old classical css files in less/sass or stylus syntax.

  • eeean

    CSS Preprocessors are a menace. Accept that you don’t write effective CSS to begin with and learn to understand the cascade as it was intended.

    • http://umbraprojekt.pl mingos

      The problem is that the client pays you for the time you spend coding and maintaining the site. With CSS preprocessors, you often end up spending less time maintaining your stylesheets, thus either your client saves money or you earn extra. The inefficiencies might matter only with really huge stylesheets, and even in those cases I doubt your Average Joe will notice that the layout engine of his browser takes an extra fraction of a second to do its work.

  • elkaz

    There is also a great .NET extension for LESS CSS that I have used on a couple of large projects now (one in particular that required different colours for each main section of the website) and I found this method of writing CSS (i.e. using variables and nested selectors) to be invaluable

    To use LESS in your .NET project all you need to do is add 1 reference and a configuration line to your web.config and your application will be reading compiled .less extensions straight away. http://www.dotlesscss.org/

  • Richard

    One of the most important differences, between SASS and LESS at least, is that SASS provide syntax for looping.

  • http://scottyapp.com Martin Wawrusch

    So you guys missed the most important aspect of SASS: compass-style.org, which puts it way ahead of the other two. I personally love the syntax of stylus, which is similar to the original SASS syntax but for larger projects SASS+Compass is a must.

    • http://www.robertmesserle.com Robert Messerle

      You should look into Nib for Stylus – it adds most of the Compass features. I tend to use SASS/Compass for my Ruby projects, and Stylus/Nib for my Node.js projects, but I definitely prefer Stylus/Nib.

  • http://www.redcrown.co Matthew

    I really enjoy using these preprocessors, but I found I had a tendency to end up with excessively nested selectors.

  • Chris

    I don’t get the love for recompiling every CSS file on the site every time something changes. It seems like a ton of process if you are working on a large modular site that needs lots of includes. I also don’t get the love for JavaScript compilation of CSS files on the client side. Seems like it could cause performance issues.

  • http://azzcatdesign.com Catherine Azzarello

    I’m surprised no one has mentioned the awesome compilers from Bryan D K Jones/@bdkjones. First there was this one: http://incident57.com/less/. Notable is that it allows you to compile locally and deliver a standard .css file w/o .js.

    Now, Bryan has released a bigger, better compiler: http://incident57.com/codekit/. This sweetheart covers lots of things, including LESS, SASS & Stylus.

    Don’t miss the awesomeness of frameworks written in LESS, namely http://twitter.github.com/bootstrap/index.html, http://p.erkins.com/ and Foundation’s LESS branch: https://github.com/zurb/foundation/tree/less.

    Once you’ve gotten comfortable using a preprocessor, you’ll never go back to writing CSS longhand.

  • Martin O.

    Hello, i wrote CSS with Stylus and CodeKit, but when i use gradient CSS3:

    filter: progid:DXImageTransform.Microsoft.gradient(GradientType=1,StartColorStr=’#ffffc1′, EndColorStr=’#efef95′);

    CodeKit send error. And it is very bad, because, i must comment this line
    and after that i must uncomment same line.

    • http://twitter.com/johnathancroom Johnathan Croom
      Author

      Try replacing your line with this is Stylus:

      @css {
      body {
      filter: progid:DXImageTransform.Microsoft.gradient(GradientType=1,StartColorStr=’#ffffc1′, EndColorStr=’#efef95′);
      }
      }

      The junk above isn’t proper CSS and that’s why it throws an error, but surrounding it in the @css will escape it and it should not error when CodeKit compiles it.

  • Abdallah

    I suggest compass.
    what do you say?

  • http://www.ferdychristant.com Ferdy

    Solid comparison and great discussion in the comments. I do like to comment on this introduction text:

    “CSS3 preprocessors are languages written for the sole purpose of adding cool, inventive features to CSS without breaking browser compatibility.”

    I don’t entirely agree with this statement. I think the sole purpose of these CSS preprocessors is to bring relief in maintaining large and complex CSS. To promote reuse, to avoid writing bulky syntax by hand over and over again. It’s not about cool features or adding features, it’s about getting existing CSS better organized.

  • firdaus

    what ever it is, i do manual coding ..

  • Matija

    “Preprocessors produce CSS that works in all browsers”?! That’s really wrong… It’s entirely up to the designer to provide browser-specific solutions to a problem. I’m not so good at creating definitions, but something like this would be much better: “CSS preprocessors increase the speed and efficiency of creating stylesheets and allow reducing the amount of non-semantic HTML elements”.

    The article is a bit disappointing, it is mostly talking about the basics of a CSS preprocessor, rather than assuming the reader already knows that. After reading it, I still didn’t have any idea which one to pick, because the article basically says “try them out and decide which one is better” and we already knew that. Maybe the title of the article should’ve been something like “CSS Preprocessors and Why They Are Great”.

  • Wouter J

    I have used SASS for a time now, but I recently switch to Stylus. I really enjoy the syntax they had and the dynamic (like Ruby who I used to use).

  • janw

    I looked into all before.
    The problem I have is IDE support.
    Netbeans remember which colors you use so on auto-completion it will show the color, both in # and color.
    With one of these I can’t even auto-complete the property like ‘padding’.

    So until Support gets beter I’m remainingto use boring css

    • http://umbraprojekt.pl mingos

      Have you tried the IDEs from JetBrains? I use PhpStorm, but afaik, all of their web-related IDEs share native support for SASS and LESS.

      • Spot

        I haven’t tried the native SASS/LESS support, but good to see another JetBrains user, PHPStorm is great! Highly recommended.

  • Robert Kalyebbi

    I will try out LESS.

    But does LESS work on IE?

  • http://twitter.com/jitendravyas Jitendra Vyas

    Your example of Nesting is wrong.

    You wrote

    &:hover {
    text-decoration: underline;
    }

    While it should be

    &:hover {
    text-decoration: underline;
    }

    • http://twitter.com/jitendravyas Jitendra Vyas

      &:hover should be &:hover

  • http://tomleo.com Tom

    Until now I had no interest in CSS preprocessors because CSS is simple enough as it is. However I really like the idea of Mixins, I think they can save me a lot of time!

  • http://www.alphascore.com Matt S

    I really like the comparison in regards to the syntax but it seemed to me one glaring feature that was missed is how all these preprocessors get compiled. I know with SASS you can precompile them so you don’t take a performance hit either on the server or client. I’m not quite sure about LESS and to be honest this is first I’ve ever heard of stylus.

    Does anyone know the details of how each get compiled? The last I heard LESS was compiled client side using JS? To me that doesn’t sound efficient but maybe I’m wrong.

    • http://twitter.com/johnathancroom Johnathan Croom
      Author

      Preprocessors should be compiled locally. All three of them have command line tools for compiling.

      As you stated LESS can compile on the client-side. While this may be alright during development, I would avoid it elsewhere because of performance issues.

      There are also tools that auto-compile CSS for you, one of them being CodeKit.

  • Sean Curtis

    Saw this post about setting up a nice workflow using Sublime Text and CSS/JS pre-processors: http://tarantsov.com/blog/2012/02/sublime-text-workflow-that-beats-coda-and-espresso/

  • David

    So after a long and detailed post comparing them to each other, it was finally established that all 3 preprocessors are pretty darn similar.

    It really makes no difference which one you choose. The post should really have explained how each are applied and installed, rather than just their functions, as that is quite a vital part of preprocessors.

    Frankly, using Compass + SASS (the oldskool version, not the annoying bracketed new version) and typing in “compass watch .” in your terminal makes for a much more pleasant experience than having to install another application to process your CSS before it’s uploaded to the server.

    To anybody that says that LESS is great because it can be “compiled on the fly in your browser” – that’s just terribly bad practice and poor web development. You never “assume” a client has something enabled, and you always have javascript/flash/etc fallbacks. If you process LESS files directly on the browser, and the client disables javascript… POOF, no more styles for him. Not a smart idea.

    • L.

      I respectfully disagree.

      I code only webapps and I have absolutely no fallback for no JS support.

      Neither do I support IE6.0 or fail browsers (Opera, Safari and other no-market-share-browsers).

      IMHO, it’s all a matter of what you’re trying to do and who you’re selling it to.

      My humble opinion being that if some viewer has no JS or IE 6.0 the only fallback there is a big line saying : install chrome/firefox/IE8+ and quit disabling js, thanks.

      This is 2012, and as webdevs you have a responsibility to push for html 5 / css3 standards (or else you can just continue pulling hair/ designing crap in the ie6.0 compatible world).

      Fight for code sanity !

      • http://www.hostinsight.com/ hostinsight.com

        I know this is an old thread, but anyone else reading this. CodeKit is an amazing little app that converts SASS, LESS, Stylus and more for you into plain vanilla CSS. No JS required. I love it.

  • http://lebenplusplus.de/ Gabriel

    If you don’t like to install Ruby for SASS and have a PHP interpreter on you web server, try phamlphp (http://code.google.com/p/phamlp/ ), a PHP library that can compile SASS to PHP. It even caches the compiled CSS so there is no performance hit.