Na navigaci | Klávesové zkratky

SASS, LESS, Stylus or pure CSS? (3)

Journey into the heart of the three most known CSS preprocessors continues, though not in the way I originally planned.

CSS preprocessor is a tool that take code written in their own syntax and generates the CSS for the browser. The most popular preprocessors are SASS, LESS and Stylus. We have talked about installation and syntax + mixins. All three preprocessors have a fundamentally different way of mixins conception.

Each of them have gallery of finished mixins: For SASS there is a comprehensive Compass, the LESS has framework Twitter Bootstrap or small Elements a Stylus NIB.

… this was opening sentences of article I started write year and quarter ago and never finished. I came to the conclusion that all three preprocessors are useless. They required to do so many compromises that potential benefits seemed insignificant. Today I will explain it.

CSS preprocessor is not something I can use from scratch. I'm not a complete novice with CSS, I have a 10 year history, and now I have a mature system and preprocessor should fit in it. How does this system look like? According to me, nothing unusual.

If you look under the hood of this blog, you will find that the server sends just one CSS file and just one JS, both minimized. And file combined.css contains styles for all devices, i.e. screen, printer, mobile phones, retina, etc. Uncompressed looks like this:

@import ",latin-ext";

@import "libs/reset.css";
@import "libs/classes.css";

@import "libs/fshl.css" screen;
@import "fancybox/jquery.fancybox.css" screen;
@import "layout.css" screen;
@import "homepage.css" screen;

@import "libs/print.css" print;
@import "print.css" print;

The entire stylesheet is divided into a number of smaller units. In the libs there is a small CSS framework that defines the basic rules that shares all my projects (btw reset.css is nothing weird as Eric Meyer's reset, but rather something like this), there are styles for used components and the rest of website. Most of the @import rules are media-dependent, so they are applied only to the printer or screen etc.

In stylesheet I like to use indentation, which fundamentally improves readability:

a {
	padding: 3px;
	margin: 0 -3px;
	text-decoration: none;

	a:hover, a:active, a:focus {
		color: white;
		background-color: blue;

article {
	margin: 2em 0;

	article hr {
		visibility: visible;
		clear: none;

	article footer {
		margin-top: 2em;

I must emphasize that this all is plain CSS 2.0, which correctly displays any browser. The only requirement is that the rules @import must be placed at the beginning of the file, before anything else. Inside included files it is possible to include other files or use media queries, allowing tuning for mobile devices or loading images in a higher resolution for retina displays (the browser correctly combines media query in the file with the media specified within @import rule).

The whole structure could be uploaded to server and it will normally work. But I wrote a simple script which all the @imported files combines to a single file, minimizes it and then uploads to the server. It has a good impact on the speed of page loading, especially if you're reading in places with bad internet connection.

And to this ecosystem I wanted bring CSS preprocessor. It should, of course, take place of the CSS combinator and allow me better address some of the CSS lacks.

How foolish I was!

Preprocessors ignore @imported files unless you change their extension from .css to the proprietary one (ie .less, .scss, .sass. or .styl). This is annoying, you lost associations with applications, in some editors will not work syntax highlighting etc. Well, what can I do. (It is entirely proper to use proprietary extensions, I am just talking about @import, which cannot process CSS files, as SASS states, CSS is subset of SCSS syntax, and you need to rename extension).

Suddenly I see that I have lost some images. Why? For example, jquery.fancybox.css contains a definition of background-image: url ('fancybox_sprite.png'), both files are located in the subdirectory fancybox. When we combine styles from different directories into a single file, of course, we have to transpose all relative paths. It gives common sense. And, of course, this is what the browsers when evaluate @import do, this do the mentioned 15 lines long stupidos function in FTP deployment too, only preprocessors don't and generate crippled output. Really ☹

I was unable to figured out a way how to bypass this defect. Make a mess in the folder and move all images to the root directory? Modify the paths in styles? In the styles of third parties?

But the misery is far from over…

CSS preprocessors can not handle even with media-dependent @import:

@import "fancybox/jquery.fancybox.css" screen;

You have to remove screen from import and wrap the entire contents of the included file in @media screen {... } (Except for SASS, it allows you use @media screen { @import "style.css"}). Besides to that I don't want to modify files, especially not third parties files, because it complicates future updates, these modifications could be non-trivial. For example, fancybox.css itself contains@media queries for retina and the question is, how preprocessor can handle nested media queries. They have big problems with it.

And that's not all!

The significant is how reprocessors understand my existing CSS files (which extension I was forced to change). Great, SASS and LESS was confused only with =padding: 0 (LESS casually reported syntax error on quite a different line), it is the legendary underscore hack for IE6 in version for IE7. No problem, I deleted this obsolete rule and everything worked.

Not so in the case of a Stylus (and I admit that it was my favourite one). It crashes with indentation. It said unexpected 'indent' and finito. Just ordinary comment makes Stylus cry in a corner.

My friends, I could use CSS preprocessor, but I have to totally fuck up my clean directory structure and drastically modify styles and styles of third parties. For benefits of mixins and variables? No, thank you ?

And I am not talking about tons of bugs in LESS and Stylus. Stylus is unable to do as basic tasks as move @import rules to the top of the file and generate valid CSS. Sad. *(Please do not write me that you are using a preprocessor and everything works for you, it's just as silly as when doctor refuses to treat fracture of your leg, because his leg does not hurt at all.) *

A year and quarter later

This happened a year and quarter ago. Very long time for hot technologies development. That time I reported all discovered bugs and today I'd like to see what is new with our three friends.

  • SASS maintains sassus quo, all the weaknesses and strengths remain.
  • Stylus? Total disappointment. It can now deal with relative paths (with option -r) but no bug was solved and author now works on new preprocessor.
  • LESS. A year ago outsider, today it generates perfect CSS. Wow!

LESS makes me very happy! Yes, I did not use any advanced features and I am just happy about the fact that LESS understand CSS at least as IE6 did, and can generate (with option -ru) valid merged file, a skeptic might argue that this is not so revolutionary achievement, but in the world of CSS preprocessors it is amazin success, it warmed my heart, years of intensive development was not useless!


You might be interested in


  1. Martin Andersson #1


    Thank you for your insightful thoughts!

    9 years ago

This article has been closed. It is no longer possible to add comments.

phpFashion © 2004, 2024 David Grudl | o blogu

Ukázky zdrojových kódů smíte používat s uvedením autora a URL tohoto webu bez dalších omezení.