My thoughts on LESS

19 July 2010, in CSS, Tools | 21 comments »

I’ve started using LESS a few months ago on a few projects. LESS allows you to extend the way you write CSS, letting you use variables, nested selectors, operations and mixins. It sounds great — and it is great — but there are a few things that can make it work against you. These are some of my thoughts on LESS.

What is LESS?

LESS — Leaner CSS — is, in the authors’ own words, a “new version of CSS” (better yet, of writing CSS), that is then compiled into “traditional” CSS using the LESS compiler.

There are 4 main things you can do with LESS that you can’t with normal CSS:

1. Variables

You can define a variable, such as “@text-color”, and use it throughout your stylesheet. If the colour of your text changes, you only need to change it once in your CSS — where the variable is initially defined.

2. Nested selectors

With nested selectors, instead of doing this and repeating yourself:

aside h1 { font-size: 24px; }
aside h2 { font-size: 18px; }

You can have:

aside {
	h1 { font-size: 24px; }
	h2 { font-size: 18px; }
}

3. Operations

You can add, subtract, divide and multiply using operations. Here’s a quick example:

@wrappers: 600px;

aside {
    width: @wrappers / 2;
}

This is definitely not the best example, but it should be enough for you to get the point.

4. Mixins

Mixins work a lot like variables, but you can specify a whole class in one. For example:

.b-radius {
	-moz-border-radius: 5px;
	-webkit-border-radius: 5px;
	border-radius: 5px;
}

.box {
	.b-radius;
}

From these examples, I suppose you can say that LESS is actually more. (I’m sorry, I couldn’t help myself.)

This is not a “how to” guide

The official LESS documentation is very clear on how to install it. I have to admit I usually stop reading instructions whenever “Terminal” is mentioned (and I know more people do), but I guess most CSS authors will be OK with it — if not, ask for help to your nearest web dev (or email me and I’ll give you the phone number of one).

After it’s installed, you’ll have two files: the .less file — this is the file you’ll be working with — and the compiled .css file.

There’s also LESS app, that makes it easier to use LESS. And I suppose that some CMS and servers let you use LESS directly, but the point of this article is not to teach anyone how to install it — it’s to go through its good and bad points.

On to the important bit…

How LESS can make your life easier

This is a list of things that, in my opinion, make LESS worthwhile and can really simplify your CSS. These are the things that I usually miss the most when I’m not working on LESS files.

1. Variables

Surely when you are writing your CSS there are colours, measurements, etc. that you keep using over and over. For example, let’s say your brand colour is jade (very fashionable for Spring/Summer 2010). You may use it on various elements in your design, for example, the main text:

body {
    …
    color: #77b59d;
    …
}

Or the borders of your posts:

article {
    …
    border-bottom: 1px solid #77b59d;
    …
}

Or as the background of your footer:

footer {
    …
    background-color: #77b59d;
    …
}

If someone has to edit the CSS file and doesn’t know exactly which colour he or she is supposed to be using — it may even be you a few months later —, what happens is that either you’ll spend some time scanning through the document until you find the colour, you’ll use Firebug or, if you like to complicate things, use xScope or take a screenshot and use Photoshop to detect the colour.

This is silly. You’ll end up with many similar colours instead of just one. (As a note, Dreamweaver lists all the colours that a site is using — you’d be surprised at how inconsistent some CSS authors can be when applying colour.)

Another thing that may happen is when you actually want to change this colour throughout your stylesheet: you’ll have to edit every instance of it — that’s painful.

With a variable, you can have this:

@main-color: #77b59d;

body {
    …
    color: @main-color;
    …
}

article {
    …
    border-bottom: 1px solid @main-color;
    …
}

footer {
    …
    background-color: @main-color;
    …
}

Beware though: you can easily go overboard with variables. I have to confess I was inebriated in the beginning by the thought of never having to declare a colour, a padding value, etc. again, and started adding too many variables to my LESS files. It gets messy and complicated quickly. You’ll have to find a balance.

2. Accessors

If you only need to access something once, you probably don’t need a variable. If you’re pretty sure that that thing you need to access is, and will always be, directly linked to whichever thing you’re linking it to, you can use an accessor.

Let’s say you have a block with a heading and some text. You want the border of that box to always be the same colour as the heading. You can have this:

#sales {
    border-color: #ae7b2a;
}

#sales h2 {
    color: #sales['border-color']; 
}

Using accessors may be going a step too far in some cases, but in other cases it makes a lot of sense — I think they’re quite useful.

3. Mixins

One example: gradients. Let’s face it, they are an absolute pain to write. Take a look at how LESS makes it easier for you:

The mixin:

.grad-linear (@start:"", @end:"") {
    background: -webkit-gradient(linear, left top, left bottom, from(@start), to(@end));
    background: -moz-linear-gradient(-90deg,@start,@end);
}

Using the mixin in your .less file:

nav {
	.grad-linear(#b3cdcc,#718a89);
}

What your compiled .css file will show:

nav {
	background: -webkit-gradient(linear, left top, left bottom, from(#b3cdcc), to(#718a89));
	background: -moz-linear-gradient(-90deg, #b3cdcc, #718a89);
}

Mixins are great for properties that still require that we add some vendor-specific code (like border-radius) or for the latest CSS3 gradients, transitions, etc.

I have to say mixins, especially when used for gradients and border-radius, are my favourite part of LESS.

4. C-style comments

Some people prefer these to typical CSS inline comments. I’m OK with either, but if you’re using LESS, you can have either this:

/* A normal CSS comment */

Or this:

// A C-style CSS comment

5. Nesting (in some cases)

Nesting is one of those things that makes you think LESS is amazing at first. Then you start using LESS and start nesting selectors, and change your mind.

The rare instance where I think nesting is useful is with link states in simple selectors. In LESS you can have this:

a {
    :link, :visited { text-decoration:none; color:#edd273; font-weight:bold; }
    :hover, :active, :focus { color:#edd273; border-bottom:1px solid #edd273; }
}

And the output will be this:

a:link {
  text-decoration: none;
  color: #edd273;
  font-weight: bold;
}
a:visited {
  text-decoration: none;
  color: #edd273;
  font-weight: bold;
}
a:hover {
  color: #edd273;
  border-bottom: 1px solid #edd273;
}
a:active {
  color: #edd273;
  border-bottom: 1px solid #edd273;
}
a:focus {
  color: #edd273;
  border-bottom: 1px solid #edd273;
}

There’s a lot of repetition in here, I know (I’ll mention that on the next section), but it’s nice nonetheless.

How LESS can easily become a nightmare

This is a list of things that I would either avoid doing in LESS or that just don’t work the way you’d expect them to (so, annoyances).

1. Nesting (in most cases)

As I just mentioned in the previous section, nesting looks nice at first, but it doesn’t work flawlessly.

One of the things that I’ve noticed for example, is that, even though you can have this:

nav {
  ul {
    li a {
      :link { color: red; }
    }
  }
}

This won’t work (notice that now I’m using a direct child selector instead):

nav {
  ul {
    li > a {
      :link { color: red; }
    }
  }
}

For this last bit of CSS to work, you’ll have to do it like this (notice the extra “&”):

nav {
  ul {
    li > a {
      &:link { color: red; }
    }
  }
}

This not a problem with LESS, I guess it’s just not a very intuitive way of doing it just for using a different type of selector.

The main thing, however, that I think makes nesting a poor choice in most cases, is how it can make a mess out of specificity [here’s a post I’ve written previously on specificity and other matters].

Your first instinct is to nest everything inside the main blocks, like aside, #sidebar, #news, etc. But then you realise you need to reutilise a piece of the CSS for another area on the site. You make another nested selector for that new block, because you don’t want to go over that first nested block of CSS that you created in the first place. You’ll be left out with numerous redundant selectors, with very long selectors (because you don’t notice this until the compiler phase), and with the need to create overly specific selectors to override your initial ones (that shouldn’t have been so specific to begin with).

Nesting selectors is one of those cases where the phrase “with great power comes great responsibility” makes a lot of sense. Use it wisely and carefully.

2. Changes made to the compiled file

This isn’t a problem with LESS per se, but rather with your working process.

Even if you are the only person in charge of the CSS on a given project, it’s possible that someday you will leave, or hand the project over to someone else, so it’s a good thing to make sure that no-one is going to edit the compiled .css file directly instead of the .less one.

If this happens, and then after a while someone does use the .less file, when it compiles, it will override the changes made to the .css file. Then you’ll have to go back and fix it.

This is just a general problem with people: if there’s a chance that we can make a mistake, we will make it.

3. Formatting

The .css file that results from the compiler gives you back your CSS with no comments and single-line declarations (that have more than one property). It would be useful if you could have some control over this. For example, you may want to minify the CSS (although you could argue that this should be a completely separate step), keep comments in, have multi-line CSS, group selectors, etc.

I’m not entirely sure if this has been resolved, so if someone knows better, do let me know.

4. Using Firebug

I can’t work without Firebug, and one of the best things about it is knowing exactly which line you’re looking at. If you’re using LESS, that’s broken: Firebug shows you the line of the compiled .css file, not the original .less file you’re editing, which is basically useless.

Conclusion

I love LESS and I think it’s a pleasure to use, until you start trying to be too clever and things start getting messy. My advice is to use it with care, take advantage of its niceties but don’t go overboard.

I know there are lot more problems (and probably good things too) that I haven’t referred. These are the ones that I’ve personally came across with; I try not to use LESS on larger projects and I usually don’t use @import on my stylesheets (especially smaller projects) — which I know can cause some problems.

I’d love to know what your thoughts are on this: have you used it? Why, or why not? Which problems have you encountered? Do you find it helpful or just plain silly?

There are 21 comments:

  1. Antony Kennedy says:

    I’m with you. The nesting is the biggest killer. It all looks so neat and lovely in your .less file, until you compile and realise what it’s going to spit out is so ridiculously inefficient. Seems like (assuming we only have one stylesheet) the compiler ought to be able to at least calculate if nothing else has a higher specificity, and show less code.

    You didn’t mention @import, which lets you basically include other .less files inline. I have used this to keep all of my variables separate from the CSS, so that less technical designers can just work on those files, like a config file.

    Also, the latest version of Less App has a “minify” button, which is nice. Though, if you’re using TextMate the less bundle automatically compiles for you which I prefer. There also seems to be a difference between Less App and using the gem – in that some syntax that the gem has no problem with Less App throws errors on (because it is using less.js rather than the native Ruby implementation). You could have mentioned less.js – but you know my feelings on using JS libraries to introduce dependencies and achieve stuff we could do if we weren’t lazy.

    Great article. We shall have to plagiarise it for our book.

  2. Excellent article. I should be using mixins more.

    The nesting is by far my favourite feature, though you’re absolutely right about caution. I tend to start deeply nested, then pull sections out as they’re needed elsewhere. Specificity gets hard.

    I’d point you to LESSPHP, which is a great way to compile LESS. When using the ruby gem, you have to cope with an infuriating lag, which this solves.
    http://leafo.net/lessphp/

    And when it comes to file naming, I choose global.src.css and global.pub.css, instead of “.less”. That way, my syntax highlighters don’t need extra configuration, and it’s clear to any future editor what the source and result files are.
    eg: http://mclaren.com/_assets/css/site/global.src.css

  3. Daniela Egerland says:

    This is the first deeper approach to LESS I have read. I am still considering the options because, as you stated, other people may edit my css file where I work, so I will need to have a talk with all of them. Thanks a lot though, I love the idea of LESS. Awesome.

  4. Antony Kennedy says:

    @Daniela – As Kenneth points out above, if we can perform JIT (just in time) compilation of the CSS, on the server rather than incorporating it into our workflow, there are no CSS files for them to mess up!

    However, LESSPHP obviously only works with PHP, though you can use less.js (which I am not a fan of). Hopefully if/when Less gains popularity further options will appear like dedicated Apache modules, and plug-ins for JSP and .Net.

    • Craig Rowe says:

      http://www.dotlesscss.com/ is the .NET version if anyone’s interested btw.

      Used it a bit myself. The only issue with server side solutions, that I’ve found, is often the designers on the project are working from static templates not running (in the case of .NET) IIS with the full backend etc.

  5. helium says:

    I really like the idea of LESS but i just cant bring myself to go through the lengths required to implement a system like this. Hopefully these features / or similar will be part of the standard CSS spec.

  6. Jack Franklin says:

    You know the most recent version of less.app can run locally using Chrome’s JS engine? It converts .less files to .css straight away on save.

    Good post though, agree with you on everything.

  7. This is how CSS should be natively in the browser!

    I mean, it’s clear that there are some little kinks that need to be ironed out but for the most part what a great idea!

    I really see this sort of thing as the next step for CSS. Although the argument could be that it is no longer a stylesheet but it’s own fledgeling programming language, with what amounts to variables, functions etc. Still, I don’t see a problem with that. As we move on and expect more out of our browsers and our websites it’s only natural that the technologies we use to build them get more complicated.

    I’m interested – I can see that it could save time when maintaining a site but do you find it saves time when building it initially, as well?

  8. Antony Kennedy says:

    @Mark

    We’ve been demanding CSS variables for a long time now. The best way to get support for the kinds of things that Less supports, is to use Less now, and demonstrate more widespread demand for that in the mainstream.

    It certainly saves time when building sites, though the order of @imports and nesting can catch you out at first.

    There’s no reason you can’t try it – you can copy and paste the contents of an existing CSS file into a .less file and it will compile fine, and you can just write new stuff in Less and see what you think. You can use Less App to watch folders and compile automatically, or there is a bundle for TextMate to automatically compile every time you save.

  9. Jae Xavier says:

    Yeah I’d have to admit I went overboard on variables also.

    Great post!

  10. Great article, thanks.

    I gave it a shot inside of Espresso (had to use this trick http://wiki.macrabbit.com/index/Override_default_sugars/ to get the LESS / CSS formatted, but that’s pretty straightforward). Also using the less.app for it’s automatic compile is pretty nice – switch to the browser and hit refresh and you can see the changes with very minimal delay.

    It would be lovely to have it work inside of CSSedit – right now it seems that i would have to backport changes made in the CSS to the LESS file if i was tweaking things or developing in a more exploratory manner inside CSSedit.

  11. Comparable options available to you are Sass and Sass2. Sass has a simpler, whitespace delimited syntax, and Sass2 looks a lot like Less, with variables, mixins, @importing inline, and nested specificity.

    http://sass-lang.com/

  12. Jason Mayes says:

    I must say I was reading through this and was thinking, OK, I could live with these disadvantages – keep my “KISS” hat on and using LESS can certainly be a great tool. Then I read point 4 – oh my gosh, I am not sure why this did not occur to me prior to this, but like you, Firebug is a must have when debugging CSS issues. As you rightly mentioned, it basically becomes useless when using LESS, unless of course you can figure out what part of the LESS file generated that CSS statement FireBug is referring to. Could get nasty though. Hmmm will have to ponder on this some more. I guess this is why you posted on having some of this functionality natively in CSS3 spec rather than using a tool such as LESS alongside. :-)

  13. William Hund says:

    Nice article. I have started using OOCSS which allows similar levels of code reuse without a separate compiler. it also provides a grid system and yahoo reset. Definitely worth a look.

    https://github.com/stubbornella/oocss/wiki/

  14. Tai says:

    Has anyone used Fireless?
    The addon for Firefox which works with Firebug for LESS.

    https://addons.mozilla.org/en-US/firefox/addon/fireless-for-firebug/

    • Harshit says:

      looking for firebug supported less plugin, above one is disabled by admin, life would be easier with that.

  15. Nice article :D
    I also started a series of articles about LESS, but in portuguese :)
    and u give me more ideas of what should I write

  16. Andrew Woods says:

    i just started using LESS. I think it’s a great syntax for writing css. the mixins are particularly cool. Like all of you, i love firebug. you’re right that LESS messes with firebug’s ability with compiled css files. Two things can assist you with that. First use the CSS style comments to section your file. It’ll make it easier to find the correct section of the file. They’re preserved as long as you don’t minify the css with the -x flag. Second, keep your mixins defined in a separate file that you import. not only does it make your mixins re-usable, but you it makes your styles file shorter, and easier to find the correct styles.

  17. Arie Putranto says:

    I’m happy enough with “standard” css coding. Am not going to consider LESS neither Frameworks. Life is complicated enough …

  18. Rishabh says:

    I especially loved the conclusion part. :)

Leave a comment: