With CSS, LESS is more


I’ve got a bit of a secret – I’ve never really liked CSS.

Don’t get me wrong, it’s a nice idea. I’m certainly all for separating content and presentation. And yes, most importantly, it really does work in practice. Just take a look at any of the many CSS galleries that demonstrate how powerful it can be in hands much more talented than mine. However, just like there are some awesome php applications, it doesn’t mean I actually like php.

The problem I have with CSS is that I find I repeat myself a lot. For example, if you have a standard colour or margin width that is reused throughout a site, you have to repeat it every time it’s used. Now one of the first things I learned about programming as a kid is that if you’re repeating the same value, then put it in a variable. CSS, however, doesn’t have variables. Another example is when you have to frequently reuse a series of CSS declarations, like setting colour, font-family and font-weight. There’s no easy way to do that in CSS either. DRY is one of the most basic software engineering principles, and to be honest, CSS completely fails.

LESS is a Ruby tool that extends CSS to make developing it a more pleasant experience. It provides a language that is a superset of CSS – it’s the same language we know but adds variables, mixins (like methods) and basic arithmetic, among other things. Once you’ve written these LESS files, they will be compiled to plain CSS that will work just the same in any browser. Although LESS is a Ruby tool, it doesn’t mean you have to start developing everything in Ruby. In fact, the first project I used LESS on was a Java project, and the idea of requiring a Ruby install on every developer’s workstation and the build server was less than attractive. Fortunately, JRuby is an excellent Ruby runtime and installing a gem (such as LESS) couldn’t be easier. We even put JRuby into our project’s tools directory and checked it into source control. That enabled every developer and the build server to happily run LESS as part of the build process with absolutely no setup or installation.

To demonstrate what LESS can do, let’s start with a great example of CSS. Recently Christian Heilmann put together an excellent Sticky Note Effect demo to show how powerful CSS3 can be. If you’ve got a reasonably recent browser, check it out here.

CSS Sticky Note Demo

It’s a wonderful demo, but if you were to take a look at the CSS, you’d see a lot of repetition. For example, due to the way browsers have evolved support for some of the more recent CSS standards to define rotation, we have a large number of rules for a simple declaration.

-webkit-transform: rotate(-6deg);
-o-transform: rotate(-6deg);
-moz-transform:rotate(-6deg);

With LESS we can make this much more attractive. By simply defining a rotation mixin once with these rules, it becomes only a single statement to reuse them.

.rotate(@rotation) {
    -webkit-transform: rotate(@rotation);
    -o-transform: rotate(@rotation);
    -moz-transform:rotate(@rotation);
}

/* Then to use... */
ul li {
    .rotate(-6deg);
}

Another part of the language that I really like is the ability to nest rules. Take this example from the sticky note css:

ul{
  overflow:hidden;
  padding:3em;
}
ul li{
  margin:1em;
  float:left;
}
ul li a{
  text-decoration:none;
  color:#000;
  background:#ffc;
  /* lots more... */
}

The above is setting rules for ul elements, any li child elements of that ul and then any a elements of those li’s. In this example it’s not too bad, but imagine that the parent element was a specific id. If you wanted to change that id, you’d then have to change every rule related to it. LESS makes this scenario blissfully simple with nested rules. To write the same as the above, the following would be used:

ul{
  overflow:hidden;
  padding:3em;

  li {
    margin:1em;
    float:left;

    a {
      text-decoration:none;
      color:#000;
      background:#ffc;
      /* lots more... */
    }
  }
}

To finish these examples with where I started, LESS adds variables, which means we can define a named value once and reuse it throughout our styles. Need to change it? Just change it in one place.

@background: #666;

body {
   background-color:@background;
}

While LESS is already a super useful tool for developing CSS, the next version is shaping up to be even more exciting. LESS version 2 is written entirely in JavaScript. On the server, this will be run on node.js, but it can run directly inside the client’s browser. To demonstrate this I’ve rewritten the Sticky Note CSS in LESS, and instead of compiling it into CSS first, I’ve just included the new version of less.js and a link to the LESS file. Take a look at it here. When you hit the page, it’ll immediately download the LESS source, compile it and apply it to the page. Is this a good idea for a production deployment? Probably not. That said, it’s a very quick process so it’s an option. It’s certainly great for a demo like this and very useful during development. Dmitry Fadeyev has a great writeup on less.js here.

Find more information on LESS here. If you’re an die-hard .NET developer, you may want to check out the .NET port of LESS – dotLess.

Advertisements

4 thoughts on “With CSS, LESS is more

  1. LESS looks interesting, but your comments of “if you have a standard colour or margin width that is reused throughout a site, you have to repeat it every time it’s used.” and “when you have to frequently reuse a series of CSS declarations, like setting colour, font-family and font-weight” sound more like misuse of CSS.

    If you have standard font properties throughout a site, apply them to the body element and you don’t have to do so again. If you have multiple elements or classes using the same CSS props, then apply those to all the properties at once by comma separating the declarations: h1, ul.red, em { color:#F0F0F0; }. Setting color on each element via the LESS variable system is only going to result in a more bloated CSS file.

    Some of the stuff LESS introduces like the nested rules are quite neat, but I’d guess that it’s usefulness is largely inversely proportional to the CSS-mastery of the user…

    1. Although applying rules to multiple selectors allows you to reuse declarations, if you wanted to reuse the colour value itself on multiple properties you’d have to repeat it. Perhaps using the same color for a font and a border would have been a better example.

      There’s also more to using variables in LESS than just reuse. LESS also provides basic arithmetic operations. For example we could define the colour of a link in a variable, and then use a slightly lighter shade of that colour in it’s hover selector.

      LESS is just spitting out CSS, so it’s not doing anything that you couldn’t do otherwise. If you’re a completely comfortable CSS master, you’re probably not going to get very excited by it. However, as you point out, features like nested rules make CSS development much clearer.

    2. Comma separated declaration blocks are a way of doing it, but that’s exactly the problem: they can get large and so hard to manage as the stylesheet grows. They’re also not very logical because you’re making a separate declaration block just for the shared property, so you’ll now have two declaration blocks instead of one, making it harder to find those properties.

      LESS variables will be repeated throughout the stylesheet, but they have semantic names and are placed in their appropriate declaration blocks, which to me just feels better and simpler. Also being able to generate relative values from the same variable is invaluable, for example: set one variable for the background color of your header area, use the operation +10% to brighten the same color for the tabs, darken it a little with -20% for the borders, and so on. Changing one color will then restyle the whole header area that builds up different shades of the same color. You can also saturate and desaturate with Less.js, I think the function is: saturate(@variable, [percentage])

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s