.less – Dot Less Dynamic CSS Processor for .NET

.less logoOf the three textual formats that make up the main pillars of web development (HTML, CSS, and JavaScript), CSS has had the least attention in terms of server-side processing. HTML is obviously well covered, with frameworks such as ASP.NET. JavaScript is starting to be covered with compilers such as Google’s Closure Tools. Until now however (in the .NET world at least), there haven’t really been any CSS processors.

Luckily, that is now changing with the recent release of .less (Dot Less). This is a port of the Ruby LESS library to .NET. It’s still in beta, so be warned that the API is still in a certain amount of flux. (That’s a good thing however – I’d rather have a bit of pain in the beta stage, in return for a well-thought-out API later on). The authors are very responsive – there’s a friendly discussion group – and the couple of bugs I’ve reported have been fixed within a very short time frame. This project seems to be in very active development, and I’m extremely impressed with it. It’s so simple to use, and gives CSS development a much-needed shot in the arm, that using this library seems a no-brainer decision to me.

So what benefits does this library give you? (Examples are taken from the .less homepage).

1. Minification

The final output from .less is a compacted (or minified) version. This means you can write your CSS with as many comments and whitespace as you like, without worrying that the client-side download will be huge. This might seem like a “meh” feature, but it’s free and will have immediate beneficial effects on your bandwidth.

2. Variables

CSS doesn’t support any form of variables or macros, so constants (the worst culprit being colours) get copied around the CSS file. That’s fine until you decide that the pink-on-orange colour scheme isn’t working, and you need to make a change. .less allows you to define variables using the syntax “@name: value”, and then reference them anywhere a value would otherwise be used.

Example:

@brand_color: #4D926F;

#header {
  color: @brand_color;
}

h2 {
  color: @brand_color;
}

3. Mixins

We’re now in a second round of “browser wars”, with modern browsers providing useful features such as border-radius via non-standard extensions. We also have to cope with Internet Explorer still making use of odd syntax for features such as opacity (via filter). The upshot of this is that to define certain CSS effects, we have to provide three or four CSS style properties, to cover various browsers. Mixins allow this bloat to be ameliorated by defining a class with the desired properties, and then “mixing” them into another class.

Example:

.rounded_corners {
  -moz-border-radius: 8px;
  -webkit-border-radius: 8px;
  border-radius: 8px;
}

#header {
  .rounded_corners;
}

#footer {
  .rounded_corners;
}

4. Nested Rules

This feature is probably of least interest to me, since I favour single-line rule formatting, however if you write multi-line rules, then this could be a very useful feature. Nested rules allow “inheritance” of CSS rules, such that more specific rules may be nested within a less-specific parent rule.

Example:

#header {
  color: red;
  a {
       font-weight: bold;
       text-decoration: none;
    }
}

I could possibly see myself using it for :hover rules and the like.

5. Operations

Since I’m merging .less into an existing codebase, I haven’t yet refactored my CSS to make use of this feature. Operations allow arithmetic to be performed on expressions involving variables. For example, instead of defining variables for a colour and its lighter equivalent, you can instead just define a variable for the colour, and then computer the lighter colour.

Example:

@the-border: 1px;
@base-color: #111;

#header {
  color: @base-color * 3;
  border-left: @the-border;
  border-right: @the-border * 2;
}

#footer {
  color: (@base-color + #111) * 1.5;
}

Alternative Usage

The homepage gives instructions for a quick-up-and-running scenario, however I already had code to handle caching and combining of stylesheets, so I wanted to hook into that. It’s easily possible to process CSS as strings if desired:

// .less format CSS as string in 'input'.
var dotLessEngine = new dotless.Core.engine.ExtensibleEngineImpl( input );

// Transformed CSS now in 'css'.
var css = dotLessEngine.Css;

// Now minify...
var dotlessMinifier = new dotless.Core.minifier.Processor( css );

// Output CSS suitable for sending to client in 'output'.
var output = new string( dotlessMinifier.Output );

Leave a Reply