An Introduction to Less

April 8th 2013 by Samuel Rossille

blog-introduction-to-less-happy Less is basically almost like CSS, with more features:

Nothing less. But much more. It has everything to make you happy!

Less in a nutshell

Like CSS, less is a style sheet language. Less is easier to use that CSS and has many powerful features. Less can has to be compiled to CSS:

Killer features

This is just a quick overview the most useful features that are the bread and butter of any less stylesheet. For a full list of the features of the language, and a more detail less to CSS mapping description, go to the less website: http://lesscss.org/

Variables

First, it allows you to declare variables ...

@themeColor: #6dd;
@themeBackground: #cfe;

... which you can use wherever you need:

body {
    color: @themeColor;
    background-color: @themeBackground;
}

.floating-box {
    border: 1px solid @themeColor;
}

a, a:hover, a:focus, a:active, a:visited {
    color: @themeColor;
}

a:focus, button:focus {
    outline-color: @themeColor;
}

On top of limiting redundancy, variables allow you to make a clear distinction between what's intended to be customized later and what's hardcoded. Basically, you can have a variables section at the top of your less file, which describes the "skin" in a single place. Variables are not limited to colors. For example, you can write:

@space: 10px;
@tinySpace: 2px;

and reuse this in several places to define margins, padding and positions...

h2, h3 {
    margin-top: @space;
}

... and also other variables:

@defaultPadding: @tinySpace @space;

.notification {
    padding: @defaultPadding;
}

.popup .header {
    padding: @defaultPadding;
}

Expressions and functions

Less allows you to write very self-understanding things like:

a:hover {
    color: darken(@themeColor, 20%);
}

or

h2 {
    margin-top: (@spaceWidth * 2);
}

There are a huge lot of other very convenient functions and expressions that you can use.

Structuration

Code structuration can be achieved through rule nesting. This feature allows you to write much clearer code, because you can split each file in blocks and sub-blocks that are dedicated to a component, a CSS class that describes a user interface role, or any subset of an HTML document that is identifiable by a CSS selector. These blocks also behave as scopes for variables. For example, where in CSS you would write this:

#header {
    ...
}

#header ul {
    ...
}

#header ul > li {
    ...
}

#header ul > li.divider {
    ...
}
#header ul > li:hover {
    ...
}
#logout-link {
    ...
}

with less, you can write that:

#header {
...
    ul {
        ...
            > li {
                ...
                &.divider {
                    ...
                }
                &:hover {
                    ...
                }
            }
        }
        #logout-link {
            ...
    }
}

I will let the reader figure out which is the most readable syntax... and the origin of the "less" name.

Mixins (see them as custom "functions")

This works like a function that will be inlined at compile time, allowing sharing some style declarations with a limited use of copy/pasting.

.shadow(@spread, @color) {
    box-shadow: 0px 0px @spread @color
    -moz-box-shadow: 0px 0px @spread @color
    -webkit-box-shadow: 0px 0px @spread @color
    -ms-filter: filter:progid:DXImageTransform.Microsoft.Shadow(color=@color, Direction=135, Strength=@spread)
}

.popup {
    .shadow(10, #000);
    ...
}

.page .notification {
    .shadow(5, #888);
    ...
}

At first glance, this can seem like syntactic sugar, but it has actually a good benefit on the "purity" of the html markup. This feature provides an alternative convenient way to share the style declarations, and in many cases removes the necessity of a making a compromise by adding style information into the HTML markup. And without the hassle of (for example) making out a name that pretends to be the abstract concept behind the fact that we have a shadow on this box.

Getting started

To quickly get started with less, you will use runtime compilation (requires less setup, and more convenient during development). Insert the following lines in the html head element:

<!--  note: the rel attribute: "stylesheet/less" -->

<link rel="stylesheet/less" type="text/css"
    href="path/to/your/less/file.less" />
<!-- less from a CDN, tag must be *after* the less stylesheets. 
    If you don't like downloading from a CDN, you can download
    the file once and     for all and hots it on your site -->
<script src="http://cdnjs.cloudflare.com/ajax/libs/less.js/1.3.3/less.min.js" 
    type="text/javascript"></script>

After that, you can start using less, which reference can be found here: http://lesscss.org/#docs

Production use

In production, you might want to precompile the less code for better performance (though this task can be postponed if you don't have many or huge less files). There are two options of which I'm aware:

<plugin>
    <groupId>org.lesscss</groupId>
    <artifactId>lesscss-maven-plugin</artifactId>
    <version>1.3.3</version>
    <configuration>
        <sourceDirectory>${project.basedir}/src/main/less</sourceDirectory>
        <outputDirectory>${project.basedir}/target/generated-css</outputDirectory>
        <compress>false</compress>
        <includes>
            <include>style.less</include>
        </includes>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>compile</goal>
            </goals>
        </execution>
    </executions>
</plugin>

Conclusion

I'm very grateful to the less.js team for this great language which made my life easier and my team more productive. If you're using CSS and not less, you should at least give it a try.

Oh... and by the way, any valid .css file is a valid .less source file, so you can just rename it to .less and start using less features without changing anything to the existing code. Very slick!