The “dark sides” of LESS (and probably SASS)

LESS and SASS – two akronyms that are very popular these days. These preprocessors seem to, no they sometimes are even praised to be the saviors of CSS. Mixins, variables, nesting, math functions … All of that sounds great, like very useful additions for your everyday work with stylesheets. Well, they can be kind of useful, I can’t deny that. But …

I’ve tried out LESS recently at a small project and first it got me very excited. The possibilities seemed endless, the benefits overwhelming. First I started to rearrange and rewrite my stylsheet by nesting and indenting the proeperties nicely. It took me quite some hours and everything was nicely structured then. But! Yes, there’s the first “but” (and more to come). LESS doesn’t allow you to group selectors with the colon (,) like .myClass1, .myClass2 {[some CSS properties]}. I was very disappointed when I found out but managed to get over it.)
Sorry, I’ve written complete bullshit here. Please reference to the following paragraph for the actual problem.

I’ve tried out LESS recently at a small project and first it got me very excited. The possibilities seemed endless, the benefits overwhelming. First I started to rearrange and rewrite my styelsheet by nesting and indenting the properties nicely. It took me quite some hours and everything was nicely structured then. But! Yes, there’s the first “but” (and more to come). LESS doesn’t allow you to group selectors (with the colon combinator ,) in a certain way.
Let’s say we have defined the following rule: .myClass1 .mySubClass1 {[some CSS properties]}. But shortly after that we realize that there is another rule, let’s say .myClass2, with the exact same properties like the former. So in vanilla CSS I would just write .myClass1 .mySubClass1, .myClass2 {[some CSS properties]}. But unfortunately that’s not possible in LESS. Because this way LESS assumes that you want to prefix .myClass2 with .myClass1 and so it ends up like .myClass1 .mySubClass1, .myClass1 .myClass2 {[some CSS properties]} in the generated CSS (see more in the comments).
I was very disappointed when I found out but managed to get over it. To reference to the sample above: I mixed in the first class into the second class like .myClass2 {.myClass1 > .mySubClass1}. Unfortunately this way the properties get repeated, which isn’t the case when you combine selectors in pure CSS. Since the HTML structure was already finished and couldn’t be changed anymore I wasn’t able to create a completely new class with the given properties and add it to the desired HTML elements. A big letdown for me, especially when I want to “convert” exisiting CSS files into LESS files.

After that I wrote some mixins (which are especially useful for gradients and border-radius or to reuse other code blocks) and applied a few color functions. But! Yes, here comes the next “but”. Although my stylesheet was not too long it already took me some effort to figure out which level of nesting I’m currently in, which parent a certain child selector belongs to. And I also couldn’t use tools like Chrome’s code inspector (which I quite adore) anymore, because everything the browser sees is a compiled CSS file, there is almolst no connection between the LESS and the compiled CSS file. That also leads me to my next concern about LESS. But! Yes, the next “but”. The compiled CSS code can get pretty bloated, especially with heavy usage of mixins, that means the reuse of previousely written rules/properties. Of course, since such a mixin just gets copied and inserted. I like to do such reuse by grouping selectors (like described above), which LESS doesn’t allow me to in certain circumstances. Maybe I can overcome that with a better planning (like promoted by SMACSS or in Harry Robert’s recent article), but it still is a pretty big letdown for me.

Although I haven’t tried out SASS yet, I know that such functionality is handled better there with @extend. It doesn’t simply copy code blocks but is capable of renaming and inserting completely new selectors – which would be my personal saviour. However the biggest problem for me with CSS preprocessors is the fact that they are only “masks”, kind of “curtains” for your vanilla CSS. They don’t solve problems, they just hide them away from you. Because in the end it’s still common CSS, not more, not less (what an irony to use this word here). Oh, and there is the problem that LESS uses the @ sign for curtain functionality which can and will lead to problems with @font-face and media queries, especially if you want to “mixin” them.

Apart from that there surely are a lot of benefits and I really don’t want to slam LESS (or even SASS). It just doesn’t work for me right now. Maybe it will for you, I really hope so and if you are interested to learn it I really want to encourage you to do so. There are a ton of tutorials (even at the official website) out there, so you won’t read any best practices here. My intention is to show the “dark sides”, the aspects that seem to be overlooked by the people. I’d really be pleased if you share your experiences in the comments, what you think about LESS and SASS, how you use it and what you love about them, but also what you really hate.

  • http://blasterunited.com.au Tom Stones

    Hey Christian,

    Thanks for the article and I always enjoy reading about the dark side of anything!

    I agree that LESS introduces issues like bloat, but think that it does solve a very important problem of providing semantic css that is easy to update, through the use of mixins and variables.

    Also, you are partially incorrect about not being able to use .classname1, .classname2{}. You cannot use that syntax but .classname1, &.classname2{} will allow you to give multiple classes the same styling.

    To be fair, I didn’t know about this until you said you couldn’t and I because i am i a contriarian, I had to set out to prove you wrong, and adapted the &:hover .

    I think functions like darken are useful as well, allowing highlight states to be defined from the initial colour.

    I haven’t run into any issues with @font-face nor @mixins, but i am not saying that you can’t, i just have never come across them.

    I don’t use LESS in final products and always optimize the css before it goes live, so I agree that if you are just using less with no knowledge of CSS, it will be a bloated mess

    Anyway, Thanks for the article and while I may not have agreed with everything in it, i thoroughly enjoyed reading it.

    PS I have never tried SASS, so I have no opinion about it.

  • Tjorriemorrie

    I’m pondering about using LESS on a new project I’m doing with friends. I think the above is relevant, although I think it’ll have long-term benefits when everyone is coding the css at their own time and place. So maybe using it in collaboration is usefull, what do you think?

    • http://www.css3files.com Christian Krammer

      So you mean when you work in a team with other people?

  • sushicodeur

    I began to use Less 2 years ago, then swapped to Compass (with scss syntax). At this time I encountered problems with Less, simple additions didn’t work fine !

    On the other hand I never had problems with Compass, and the mixins provided by Compass are great especially for the css3 properties : eg. @include border-radius(4px) that generates every vendor prefixed properties are sooo nice ! Then, Compass uses a command line tool that generates your CSS as you modify your scss files, I think it’s better to have CSS generated on your dev machine, and not on your production server. When I tried Less (it may have changed), the CSS had to be generated on the fly on the server, and there is no use for that.

    I really love CSS preprocessor, but you have to be very cautious not to nest too much your selectors. It’s great for readability, but no good for the generated CSS. When you use preprocessor, always keep in mind what will your CSS be like, and keep it short, simple and straighforward… You’re always writing CSS, so don’t change your best practices.

    I think the thing I love the most from those preprocessor are… single line comments (and just don’t understand why it’s not present in CSS syntax) !

    • http://www.css3files.com Christian Krammer

      Well, just like Louis Lazaris says in his article CSS: The Good Parts single line comments are actually possible. Just add any character in front of the line you want to comment out. CSS doesn’t execute unknown or wrong properties. Of course that’s no “trick” for production work, but for a quick test that should be fine.

  • http://www.ifdattic.com Andrew

    I actually always hated to write CSS, but then I started using LESS, I started to like it, at least a little bit. I just simply can’t live without proper nesting, indentations, single line comments, etc.

    I don’t quite understand your problem with nesting selectors, maybe you could go into little bit more details on that. Because as far as I worked with LESS I had no problems with grouping selectors.

    • http://www.css3files.com Christian Krammer

      What do you think about the fact, that you can’t use tools like Firebug anymore when using LESS since the generated CSS file doesn’t correspond to it (to be exact the line numbers) anymore?

  • http://www.css3files.com Christian Krammer

    Sorry to everybody, I’ve written complete bullshit regarding the inability to group selectors with the comma (not the colon, I totally mixed that up) in LESS. Of course it’s possible to combine two selectors with , like .myClass1, .myClass2. Therefore I’ve updated the article to reflect the actual problem.

  • Antonio Antillon

    Speaking from the Sass front, you don’t have “the generated CSS file doesn’t correspond to…” problem… as this is defined by you before compiling, you just use the “line_comments” option to true and you get a comment in your css file for every defined style referencing the Sass file and line where it was declared.

    • Wouter

      But comments are not displayed in tools like Firebug, so that doesn’t really help me. Or am i missing something?

    • http://www.css3files.com Christian Krammer

      Yeah, that’s a great help. I really have to make a deeper look at SASS. It looks really promising, but I can’t find some time to do it.

    • socialblogsite

      If you don’t have problems because “you defined them yourself”. Tell me what line the h1 color was in your project 8months ago. I’ll be generous. Tell me about the code you did last week.
      EXACTLY. Saying “because you just did it is idiotic, unless you really believe everyone has photographic memory, in which case the idea is just wrong but we can’t blame you for saying it because you really believe it.

  • http://www.ifdattic.com Andrew

    Of course it’s not as easy as using ‘Go to line..’, but with searching for wanted selector I easily get to/near the wanted line.

    I’m also become crazy about aesthetics so proper indentation and adding “// end .some-class” to the ‘}’ of each selector really helps to better navigate the LESS file.

  • http://joacim-boive.com Joacim Boive

    Just tested your LESS example:

    .class1 .subClass1, .class2{
    	font-weight: bold;
    }

    it compiles, as expected to:

    .class1 .subClass1,
    .class2 {
      font-weight: bold;
    }

    I wonder if you’ve got a problem somewhere.

    Regarding bloat, that’s not the fault of LESS. If you nest everything, then sure – it will get bloated. But that isn’t a requirement. Only nest where appropriate and you won’t get any bloat. SASS is supposed to be smarter in this regard, as it can group automagically when using nesting where as LESS can’t.

    What might be a problem is that you can’t use FireBug / Chrome Dev Tools line number straight up. For SASS there’s an addon for FireFox that supposed to let you do just that: https://addons.mozilla.org/en-US/firefox/addon/firesass-for-firebug/
    (Haven’t evaluated it properly yet).

    Not aware of any addon for LESS just yet.

    This annoyed me in the beginning but was actually less of an issue then I first thought.

    • http://www.css3files.com Christian Krammer

      Maybe I still haven’t properly stated what the problem is. I have one nested class:

      .myClass1 {
         [some css properties]
      
         .mySubClass1 {
              [some css properties]
         }
      }

      Now I want that .myClass2 to take the properties of .mySubClass1, so I would have to write:

      .myClass1 {
         [some css properties]
      
         .mySubClass1, .myClass2 {
              [some css properties]
         }
      }

      And that now becomes the following in the generated CSS:

      .myClass1 {[some css properties]}
      
      .myClass1 .mySubClass1 {[some css properties]}
      
      .myClass1 .mySubClass1 .myClass2 {[some css properties]}

      SASS is also not able to provide this functionality, but with @extend it is at least possible to build around it.

    • socialblogsite

      The question is: Where is class2 element in the DOM? is it nested inside class1?
      I would wave expected it to affect only class2 elements inside class1, because you defined it inside it, but it seems odd that the result you provided was generated as if there were no comma after mysubclass1.
      Are you sure you used commas? (you called them colons up there!)

  • http://joacim-boive.com Joacim Boive

    Ok, now even I get it! =)

    Yes, in that case the end result is incorrect.

    You could write your LESS file like this:

    .class1{
    color: red;

    .subClass1{
    font-weight : bold;
    }
    }

    .class2{
    .class1 .subClass1;
    }

    But then the result is bloated:

    .class1 {
    color: red;
    }
    .class1 .subClass1 {
    font-weight: bold;
    }
    .class2 {
    font-weight: bold;
    }

    But, if it’s an issue, then simply use CSS like you normally would:

    .class1 {
    color: red;
    }
    .class1 .subClass1, .class2 {
    font-weight: bold;
    }

  • Evert

    I just use preprocessors for variables. Basically I define colors, fonts and measurements (like grid and vertical rhythm) for which LESS is actually better than SASS (inline js). And I write my selectors like I do in normal CSS. Never used mixins etc. It feels wrong somehow and prone to errors (as you proved). And frankly putting a selector inside another selector makes it unreadable to me. I always compile my less files to css, even on development server, so I never load the actual less file and hence do not have the “doesn’t correspond…” problem.

  • Nick

    THANK YOU, I agree… the end result is what i’m focusing on

  • Deboborah

    Hi, Ive come to a very similar conclusion. While less is fun and makes codindind CSS very efficient, the debugging after does the opposite for you spend even more time trying to figure out what’s going on cause firebugs can’t point you to the exact line. I’ve also learned not to nest too deep, for ever you want to go back and use cascading to overwrite you have to use long lines of selectors to do so. Plus it does bloat the CSS which is not good for small file sizes. Ive been looking for a less compiler like sass guard gem that can compile as you go and use the CSS file in production. But at the moment I o not think I would recommend this tool, cool yes, but not the best solution.

  • http://nataliav.me Natalia Ventre

    Christian, I totally disagree with your article, there is no darkside of LESS. The first issue is a syntax mistake and you should have used & as someone pointed above.

    Deep nesting is a bad idea, in vanilla CSS and with any pre-processor, so don’t blame LESS.

    And finally the mixins, if you have many classes that share the same style, you could create a new class or comma separate the selectors or use the @extend directive (Sass and Stylus only). Mixins are great to add vendor prefixes and that kind of stuff, but it doesn’t mean that you should make everything a mixin.

  • EpF

    This is a reply to comment 12, Christian’s elaboration on the sub-class problem:

    I’m using the PHP version of LESS (http://leafo.net/lessphp/), and I don’t have the subclass problem you describe.

    Here’s the input and output I get, copied and pasted exactly:
    LESS~

    .myClass1 {
       z-index:1;
    
       .mySubClass1,
       .myClass2 {
            z-index:2;
       }
    }
    

    CSS~

    .myClass1 { z-index:1; }
    .myClass1 .mySubClass1, .myClass1 .myClass2 { z-index:2; }
    
  • John Dewiele

    Hello,

    I’ve never worked with LESS or any other tools like that. Though, isn’t the big disadvantage of such things that it can not work without javascript enabled in the browser?

    Or am I seing this wrong?

    • http://www.css3files.com Christian Krammer

      You don’t need JavaScript for LESS to work. There is also a compiler which “reads” your LESS file and “converts” it into plain CSS. That’s the way most of the people handle LESS, since it’s the most comfortable. Such compilers are WinLESS or SimpLESS. For SASS you can use Compass.app.

    • Dennis Thompson

      If you’re using a *nix macine (that is Linux or Mac) then you can install Node Package Manager (npm) and install LESS that way. The JavaScript file exists to parse LESS via ajax. You should never use this in any type of production environment. Also, compass app is crap, use command line. Compass is very well documented even if you’re new to command line.

    • http://twitter.com/Chris_Krammer Christian Krammer

      Why is Compass.app crap? I use it for several months now and I’m pretty satisfied. It has its quirks indeed, but most of the time you get what you paid for. I’d never use SASS without such a parser, not everybody likes to fiddle around at the command line.

    • Chris_Krammer

      Why is Compass.app crap? I use it for several months now and I’m pretty satisfied. It has its quirks indeed, but most of the time you get what you paid for. I’d never use SASS without such a parser, not everybody likes to fiddle around at the command line.

    • Josh M. Frankel

      I would also suggest if you using *nix with Sass looking into guard-sass or guard-compass. Much faster than some of the alternatives and strictly command line.

  • http://cameronspear.com CWSpear

    If you use compression (and you should, it’s pretty easy and the benefits are huge), then a LOT of the bloat goes away. Because there is a lot of repetitive code, that compresses really well. The end result is usually a small difference from using a pre-processor and not using one. And the time saved well makes up for that.

    If you are still having issues with the relatively slightly larger compressed files, losslessly compress some of your images. You’ll make up a lot more weight that way than not using a pre-processor.

  • Alex

    Try using Stylus instead, and you won’t need to worry about those issues. Also, for an added bonus, use the nib library as well – crossbrowser css3 mixins – made my life a whole lot easier when it comes to reading and maintaining my source file.

  • Henry

    You say (and probably Sass) and you’ve not used it! Get your facts straight before you publish such a misleading article!

  • bluefishsign

    I know this is a year old post but I just came across it. Although I do agree it can become a nightmare to read, you don’t have to code it that way. There is such thing as combining the CSS structure and SASS together. Mixins, variables, and extends are there to assist you. You don’t have to rely on them heavily and you don’t have to use everything all at once.

    I just love the fact that I can use variables and nesting where I need it. I always hated the CSS redundancy. With or without a preprocessor, you still need to shrink your CSS files. If you are having a hard time reading what another developer has done, than it is on the developer for not commenting or organizing the files correctly.