Less: The World’s Most Misunderstood
CSS Pre-processor*

Part 1: Less vs. Sass

* hat tip to Douglas Crockford for this title

For the last several years, I’ve been a core member of the volunteer Less team. Part of my job is to work with people in the Less community: answer questions, respond to issues on Github, etc. During that time, I’ve found that there are some fundamental misunderstandings about Less, especially when it is compared to Sass, and perhaps even because it’s compared to Sass.

One of the things you often see in a web development article about pre-processors is a set of simple examples like the following:

Sass (SCSS)

$color: red;
.my-element {
  color: $color;
}

Less

@color: red;
.my-element {
  color: @color;
}

In this case, the output will be very similar and predictable. The element will have a foreground color of red. But did the same thing happen?

The Answer May Surprise You

Based on that Upworthy-worthy heading, you may have guessed that the answer is no. That’s because Less and Sass, while syntactically similar, are fundamentally different in an important way:

  • Less is a declarative language.
  • Sass is an imperative language.

“Whaaaaaat?”

It’s true. And in case you need a quick refresher on imperative and declarative languages, a declarative language describes to a machine what we want, and an imperative language tells the machine how to do it.

If that’s still a little abstract, we can compare it to other languages of the web.

Declarative

  • HTML
  • CSS
  • Less

Imperative

  • JavaScript
  • PHP
  • Sass

What that means is that Less extends the CSS language under the same declarative model, whereas Sass is a programming language whose syntax is based on CSS. Another way of saying it: both Less and Sass look like CSS, but Sass does not act like CSS.

Now, in practice, knowing that Less is declarative and Sass is imperative isn’t really that important when learning one language or the other (nor is this going to be one of those articles that declares “a winner” based on attributes of the language), but it can help you understand some of the basic concepts of each.

For instance, like JavaScript, you can think of a Sass file as “running from top to bottom”. It runs like a script.

A Less file, on the other hand, evaluates values, and creates a “final value” for that particular scope, which is the same whether it’s at the top or the bottom.

The description of Less’s scope might sound more complex until you realize that you’re already familiar with it in CSS, and rely on it all the time. Here, let me show you:

.box {
  animation: fade-in 5s;
}

@keyframes fade-in {
  0%   { opacity: 0; }
  100% { opacity: 1; }
}

The fact that the keyframes are declared “after” when they are used does not matter in CSS. If it’s defined anywhere, it can be used anywhere. Less is the same way. Let’s reverse the example at the beginning of this post.

.my-element {
  color: @color;
}
@color: red;

Just like CSS, Less doesn’t mind what order something is declared, so long as it is declared somewhere. It outputs:

.my-element {
  color: red;
}

Now let’s flip Sass.

.my-element {
  color: $color;
}
$color: red;

As expected, Sass outputs:

Undefined variable: "$color"

Sass hasn’t “run through” that part of the script, so, unlike CSS/Less it doesn’t know the value of $color.

Let’s take another example of “variable-like” behavior in CSS and compare to the two languages. This time with the currentColor value of CSS. Here’s an example I came across this week, in a 2011 article from css-tricks.com:

div {
  color: red;
  border: 5px solid currentColor;
  box-shadow: 0 0 5px currentColor;
  color: black;

}
Chris Coyier notes in that article that the value of currentColor won’t be red; it will be black. Because, as you know from CSS 101, the foreground color for that div will be black. As CSS is not a “script” that runs from top to bottom, the “final value” is the one that’s last within the declaration. Less follows this same declarative model. Let’s watch!

div {
  @color: red;
  border: 5px solid @color;
  box-shadow: 0 0 5px @color;
  @color: black;

}

This outputs:

div {
  border: 5px solid black;
  box-shadow: 0 0 5px black;
}

Now, let’s check Sass’s homework.

div {
  $color: red;
  border: 5px solid $color;
  box-shadow: 0 0 5px $color;
  $color: black;
}

The output is:

div {
  border: 5px solid red;
  box-shadow: 0 0 5px red;
}

Note that Sass is not “wrong”. I’m just illustrating that it operates as an imperative language. An equivalent example to Sass would probably not be CSS’s currentColor, but something more like JavaScript.

color = 'red';
div = {
  border: '5px solid ' + color,
  boxShadow: '0 0 5px ' + color
};
color = 'black';

console.log(div);

The output is:

{border: "5px solid red", boxShadow: "0 0 5px red"}

It’s Not Your Fault

One thing that’s led to some confusion about Less’s variables has been in the documented descriptions. The original Less docs used to say Less’s variables were actually constants, which is not true, because they’re not immutable. Now, the docs say that variables are “lazy-loaded”, because they can be used before being declared. Which is also not really true. They are not used before they are declared. Lazy-loading implies a kind of imperative paradigm, and many users initially believe that Less is imperative even though CSS is not.

What Less has is an evaluation order. The value of variables have to be determined in a particular scope before dependent values can be determined, no matter what the placement of those declarations and values are. Although, like CSS, if you do declare a variable more than once, then the last value is the final value.

This is part of the cascade in CSS. The color property is not “lazy-loaded” when you reference it via currentColor. That’s simply the current color value for that element. Probably the Less documentation should say simply that variables cascade, but it’s unclear if people would intuit the behavior based on that description. We’re working on it.

What’s also contributed to this misunderstanding is in online articles about Sass and Less. This Smashing Magazine article says, “The only difference in variables between LESS [sic] and Sass is that, while LESS uses @, Sass uses $.” Well… not really. However, that article does go on to explain the concept of scoping, which is a concept present in Less and not Sass, and another important difference that I’m not going to delve into at the moment. The concept of scope is used extensively in Less, and would be a little to broad of a subject to fit within the scope (SEE WHAT I DID THERE) of this article.

As far as which model, declarative or imperative, is more intuitive? It’s hard to say. If you work with both declarative and imperative languages, either result can be intuitive if you know what mental model you’re using.

“No. Pick a Winner. The Internet is About Making Other People Wrong.”

Okay, my (biased) opinion is that having a language that looks like CSS, a declarative language, but which behaves differently from the language it’s extending is somewhat strange. Sass takes a language where properties are bound to a selector, and then runs through them like a script. However, that’s not entirely wacky, as this was the same model of Classic ASP and traditional PHP, where script blocks are interspersed through the declarative language of HTML.

More importantly, when I was first delving into the world of CSS pre-processors, I was working at a web design shop where a lot of the people who worked with CSS every day did not know any JavaScript. And one of my responsibilities was training staff in newer web technologies. Therefore, choosing Less over Sass was obvious to me, as Less presented as much more teachable to someone who already knew CSS (but didn’t know JavaScript). The two languages are conceptually very similar, and Less adds fewer new concepts for someone to have to learn.

(Note: it’s also the reason I built Crunch, for that specific web team, because I knew that requiring them to type on a command line in order to compile their styles would be a deal-breaker. And did you know that Crunch 2 now edits everything, not just Less/CSS, as well as compiles a number of other languages?)

(What, you thought I wasn’t going to shamelessly plug something?)

In other words, knowing CSS will help you understand the concepts of Less. And, in the case of variable-like values in CSS, and with the upcoming CSS Custom Properties syntax (a.k.a. CSS Variables), using Less can help you learn CSS, since those variables also cascade.

But the same doesn’t seem to be true for Sass. You’ll be learning a number of different disciplines at once, and some of what you get used to in Sass looks like it may make some newer features of CSS, in contrast, counter-intuitive. I think of Sass as a script operating on your styles (like traditional PHP does with HTML), whereas Less adds to them, in a kind of CSS+ model.

If you’re picking a CSS pre-processor to introduce to a team, I think Less is going to be a shorter learning curve with fewer curveballs. If you’re picking one for your open-source project, Less is going to be less (haha) of a barrier to entry. There’s just less (okay I’ll stop now) to learn. Less has fewer features, on purpose, to make usage of the language as easy as possible.

“Wait, You Said Sass Has More Features. Doesn’t That Mean It’s Better?”

Is the Zune better than the iPod because it has more features? If you said, “What’s a Zune?” then that may tell you the direction that argument went in the early days of MP3 players.

“Sass Is More Popular. That Means It’s More Better.”

I’ve heard that a lot, but I’m not sure where that comes from. The Sass project has, at the time of writing this, 6,756 stars on Github, and Less has 12,848. If stars were votes, Less would appear to be more popular. (If you follow that first link, you can see the comments that inspired me to write this article.)

Regardless, “better” depends on your criteria. In fact, in Github, Less contributors often recommend Sass depending on a specific user’s use case. If you’re doing something incredibly complex with your stylesheet, and that complexity absolutely depends on features that Sass has and Less doesn’t, or if you prefer an imperative model, you should probably use Sass.

If you have average requirements or are just starting out, or know CSS but are weak on your programming skills, I would probably recommend Less. But of course I would, because I’m a Less contributor. It works for me. Use whatever works for you.

Probably the perception of the popularity of Sass comes from the fact that, currently, it has some core members and contributors who are able to devote quite a bit of time to the project, and, at the moment, are much better at evangelism than Less. That means a lot of people hear about Sass, its features, and its benefits, and the same unfortunately hasn’t been true of Less. This has contributed to it being the world’s most misunderstood CSS pre-processor. Less, right now, may have more users, but could use some help in contributions, both in code and documentation. (Go contribute!)

As an example of this misunderstanding, PostCSS, the new kid on the block, originally had some copy on their front page describing how different it was from Less and Sass. I told them that a lot of those claims were wrong, at least in the case of Less, and they said that, in truth, they really only knew Sass, and assumed Less was the same way. (I’ll be covering Less v. PostCSS in a future post. Incidentally, PostCSS’s docs were subsequently updated to something slightly less wrong.)

A Few More Tidbits

So, now that you know Less is declarative and Sass is imperative, it might help you understand some of the other design decisions in each CSS pre-processor.

Sass has script-like control directives: if, for, while, each. Those affect how a script runs.

Less has things like mixin and selector guards. Those affect how a stylesheet is evaluated.

Sass and Less look the same (or similar). They use many of the same ideas. (History tidbit: Less was, in fact, based off of an early version of Sass, but used a declarative model and CSS syntax rather than Sass’s indented syntax. Having to convert CSS to Sass’s proprietary syntax was seen as a barrier to adoption, so Sass later developed the SCSS format, which resembled Less’s approach.)

Hopefully, though, this helped you get some understanding of how the programming models for each differ, and how they compare to the language (CSS) that they are based on.

In summary: WINNER = LESS

…Just kidding.

 

In part 2 of this series, I’ll be talking about Less plugins.

“Less has plugins?”

It’s a good thing I’m writing this.

Posted by: admin