A Look at Less

A few weeks ago, I read about a new project called Less, a CSS framework that extends CSS by adding a few simple, but extremely useful features. Less’ killer concept is it uses existing CSS syntax so that CSS files are automatically valid Less files as well.

I tend to feel that CSS is complex enough as it is, and the last thing I need when building a website is an expansive CSS framework, or a separate build process for CSS files that needs its own detailed configuration. Less being what it is, I was immediately sold on it and as an experiment, converted this website’s CSS to Less, a process that took about half an hour. The finished product is on GitHub.

Installation

The install process couldn’t be easier. Assuming that you’ve installed Ruby and RubyGems from your package manager, just run the following command:

gem install less

After installing Less, a .less file is converted to .css using:

lessc source [destination]

Usage

Less’ best feature (IMO) is its support for nested rules. Where in normal CSS you’d have to mark CSS rules with long selectors, you can actually nest selectors inside of other selectors in Less. I tend to write long selectors in CSS because I find that it helps keep display logic out of HTML files, so nesting rules with Less was a natural extension for me.

/* before */
div.content
{
    ...
}

div.content ol
{
    padding: 0 0 0 20px;
}

div.content ol li
{
    text-align: justify;
    margin: 0 0 8px 0;
}
/* after */
div.content
{
    ...

    ol
    {
        padding: 0 0 0 20px;

        li
        {
            text-align: justify;
            margin: 0 0 8px 0;
        }
    }
}

Notice how well the nesting complements lists! A nice side effect of Less is that when you nest ALL your document’s CSS rules (like I’ve done with mine), the layout of your Less file starts to resemble the layout of your markup file, making rules easy to find.

Less introduces variables to CSS, a welcome addition to CSS. Using variables is very simple: define them somewhere in your Less file with @<var>: <value>; then refer to them elsewhere with @<var>.

/* primary text color, for main text body */
@primary_color: #a9a9a8;

/* secondary text color, for links, alternate text, etc. */
@secondary_color: #7d7b88;

...

a
{
    color: @secondary_color;
}

One limitation to variables is that they can’t be used with strings, a problem which I describe in more detail below.

Less also supports mixins and operations, two features I didn’t end up putting to use, but which are described very succinctly on the Less website.

Limitations

While switching over to Less, I did encounter a few problems that appear to be unsolvable as far as the framework stands today.

When writing CSS, it’s common practice to group selectors together when they share properties. For example, if we wanted both our normal links and visited links to be blue, we’d write something like the following.

a:link, a:visited
{
    color: #00f;
}

Naturally, you might want to extend this to Less’ nested rules as well.

body
{
    /* nested groups */
    a:link, a:visited
    {
        color: #00f;
    }
}

Unfortunately, if you tried to do so, Less would not output your CSS how you intended. Instead, it would write something like this:

/* this doesn't work as we would have expected */
body a:link, a:visited
{
    color: #00f;
}

For these groups to work as we intended, both groups would have to the full CSS selector like body a:link, body a:visited.

With the addition of variables, a logical step would be start using them to store string fragments that could be joined with other fragments to build something useful, like a URL:

@my_images: "http://mutelight.org/images/";

body
{
    background: #000 url(@my_images + "back.png");
}

Less doesn’t seem to like this right now, but hopefully it’ll make it into a future version.

Syntax Highlighting in Vim

Of course, Less just wouldn’t be as good without some sort of syntax highlighting in Vim! Fortunately, highlighting Less files as CSS works well. Just add the following line to your ~/.vimrc:

au BufRead,BufNewFile *.less setfiletype css

Posted on June 24, 2009 from Calgary

About

My name is Brandur. I'm a polyglot software engineer and part-time designer working at Heroku in San Francisco, California. I'm a Canadian expat. My name is Icelandic. Drop me a line at brandur@mutelight.org.

Aside from technology, I'm interested in energy and how it relates to our society, travel, longboarding, muay thai, symphonic metal, and the guitar.

If you liked this article, consider finding me on Twitter.