Make Your CSS Coding Easier with LESS : LESS Is More

LESS Is More: Make Your CSS Coding Easier with LESS
In recent years, CSS has matured into a very powerful way to style web pages. It's now possible to create a website's look almost entirely in CSS, with minimal use of images.
This is great, but one drawback is that CSS stylesheets are becoming longer, more complex, and harder to manage. It's not uncommon for a typical stylesheet to run into hundreds of lines of code, with a large number of interdependent rules.
For this reason, various dynamic stylesheet languages are starting to spring up. These allow you to write your CSS rules using a more flexible, powerful language that is then turned into regular CSS for the browser to interpret.
In this article you'll learn how to use LESS, an increasingly popular dynamic CSS language that you can use to streamline your CSS coding, saving you time and effort.

What is LESS?

LESS is a dynamic stylesheet language that extends the standard CSS syntax. This means that you can create a LESS stylesheet using regular CSS, and just add LESS code to the stylesheet as and when you need it.
The standard LESS compiler is written in JavaScript, so you can just include it in your web pages along with your LESS stylesheet. The compiler then converts your LESS code into CSS on the fly when the browser loads the page. There are also compilers available in other languages, as we'll see later.
LESS is easy to understand, install and use. It gives you lots of useful features, including:
  • Variables and mixins, which let you create values and rules once, then reuse them throughout your stylesheet
  • Nested rules — these can save you a lot of coding, and they make inheritance clearer
  • Operators and functions, which let you create CSS properties mathematically
  • Namespaces for grouping and encapsulating variables and mixins
  • ... and lots more!

Installing LESS in your web page

Using LESS is easy:
  1. Download the less.js JavaScript file from the LESS website.
  2. Save the file somewhere in your website, such as the document root.
  3. Write your LESS stylesheet and save it in a file called, for example, style.less in your document root.
  4. Include less.js and your LESS stylesheet file in the head section of your web pages:
    
    
    
    Make sure the link to your LESS stylesheet is before the less.js include in your head section.
That's it! When your page loads, the less.js script runs automatically, converting your LESS stylesheet rules into regular CSS rules, which are then processed by the browser.
Now that you know how to install LESS, what can you do with it? In the following sections we'll explore the features of the LESS language, and see how to use them.

Reusing values with variables

Recycle Only
The first LESS feature we'll look at is variables. These let you create a value once, then reuse that value within as many CSS declarations as you like.
To create a variable, you use the following syntax:

@variable-name: value;
For example, you can create a variable to hold one of the main colours that you use on your website. It's then easy to use that colour throughout your stylesheet:
@mainColour: #309296;

body { color: @mainColour; }
blockquote { border: 2px solid @mainColour; }
This is equivalent to writing the following CSS:
body { color: #309296; }
blockquote { border: 2px solid #309296; }

Reusing rules with mixins

As well as reusing values with variables, you can reuse whole blocks of CSS throughout your stylesheet. These are called mixins.
Any ruleset that uses a class, id or element selector can be "mixed into" any other ruleset. You mix a ruleset into another simply by including the first ruleset's selector within the second ruleset. Here's an example:
.roundedBox {
  border: 1px solid #309296;
  background-color: #eee;
  -moz-border-radius: 5px;
  -webkit-border-radius: 5px;
  border-radius: 5px;
  padding: 10px;
}

blockquote {
  font-size: 1.5em;
  .roundedBox;
}

.promo {
  width: 10em;
  .roundedBox;
}
This is equivalent to the following CSS:
.roundedBox {
  border: 2px solid #309296;
  background-color: #eee;
  -moz-border-radius: 5px;
  -webkit-border-radius: 5px;
  border-radius: 5px;
  padding: 10px;
}

blockquote {
  font-size: 1.5em;
  border: 2px solid #309296;
  background-color: #eee;
  -moz-border-radius: 5px;
  -webkit-border-radius: 5px;
  border-radius: 5px;
  padding: 10px;
}

.promo {
  width: 10em;
  border: 2px solid #309296;
  background-color: #eee;
  -moz-border-radius: 5px;
  -webkit-border-radius: 5px;
  border-radius: 5px;
  padding: 10px;
}
You can also add parameters to mixins, making them behave more like functions. Let's modify the above example so that the border radius and colour can be changed dynamically:
.roundedBox( @borderRadius, @borderColour ) {
  border: 2px solid @borderColour;
  background-color: #eee;
  -moz-border-radius: @borderRadius;
  -webkit-border-radius: @borderRadius;
  border-radius: @borderRadius;
  padding: 10px;
}

blockquote {
  font-size: 1.5em;
  .roundedBox( 5px, #6c6 );
}

.promo {
  width: 10em;
  .roundedBox( 10px, #fa6 );
}
As you can see, we've added a couple of parameters to the .roundedBox ruleset: @borderRadius and @borderColour. We use those values to define the border radius and colour inside the ruleset.
Then, when we use the mixin inside the blockquote and .promo rulesets, we specify different values for the parameters, adding a 5-pixel green border to blockquotes and a 10-pixel orange border to promo boxes.
You can also specify default values for mixin parameters. For example:
.roundedBox( @borderRadius: 5px, @borderColour: #6c6 ) {
  /* declarations here */
}

Writing concise CSS with nested rules

Nest
LESS lets you use nesting to write cascading rules more concisely. Consider the following rules for styling a navigation menu and its links:
ul#nav {
  list-style: none;
}

ul#nav li {
  display: inline;
  margin: 0; 
  padding: 0;
}

ul#nav li a {
  color: #aaa;
  font-size: 1em;
}   

ul#nav li a:hover {
  color: #000;
}
This works fine, but there's a lot of repetition in the selectors (ul#nav, ul#nav li, ul#nav li a, ul#nav li a:hover), and the inheritance isn't all that clear.
By using nesting in LESS, we can rewrite the above CSS like this:
ul#nav {
  list-style: none;

  li {
    display: inline;
    margin: 0;
    padding: 0;

    a {
      color: #aaa;
      font-size: 1em;
      &:hover { color: #000; }
    }
  }
}
The LESS compiler then converts the nested version to regular CSS code.
Not only is the nested version more concise, but it's easier to see the cascade. For example, it's obvious at a glance that all the rules relate to elements inside the ul#nav unordered list.
By the way, notice the line:
      &:hover { color: #000; }
The & (ampersand) tells LESS not to put a space between the selector's parent and the selector in the final CSS. This is handy when working with pseudo-classes such as :hover. If you miss out the ampersand like this:
    a {
      color: #aaa;
      font-size: 1em;
      :hover { color: #000; }
    }
...then LESS will produce the following CSS:
    a {
      color: #aaa;
      font-size: 1em;
    }

    a :hover { color: #000; }
Notice that LESS has put a space between the a and the :hover, which isn't what you want to happen.

Performing calculations using operators and functions

A really useful feature of LESS is the ability to use operators and functions to manipulate values. You can manipulate literal numbers, colour values and variables this way.
Here are the operators and functions you can use in LESS:
Operator / Function Description
+, -, *, / Arithmetic operators
lighten(@colour, x%) Returns the colour value @colour, lightened by x percent
darken(@colour, x%) Returns the colour value @colour, darkened by x percent
saturate(@colour, x%) Returns the colour value @colour, with saturation increased by x percent
desaturate(@colour, x%) Returns the colour value @colour, with saturation decreased by x percent
fadein(@colour, x%) Returns the colour value @colour, made x percent more opaque
fadeout(@colour, x%) Returns the colour value @colour, made x percent more transparent
spin(@colour, x) Returns the colour value @colour, with its hue shifted by x degrees on the colour wheel
hue(@colour) Returns the hue component of the colour value @colour
saturation(@colour) Returns the saturation component of the colour value @colour
lightness(@colour) Returns the lightness component of the colour value @colour
Here are some of the things you can do with operators and functions.

Example 1: Computing heading font sizes

Heading sizes
We can set a variable to store the font size for level 1 headings, then compute the sizes for the other headings based on the level 1 value:
@h1Size: 5em;

h1 { font-size: @h1Size; }
h2 { font-size: @h1Size * .8; }
h3 { font-size: @h1Size * .6; }
h4 { font-size: @h1Size * .4; }
h5 { font-size: @h1Size * .2; }

Example 2: Computing colours

Heading colours
Here's another example — setting a dark brown base colour value for level 1 headings, then computing progressively lighter shades of brown for the other heading levels:
@mainColour: #631;

h1 { color: @mainColour; }
h2 { color: lighten(@mainColour, 10%); }
h3 { color: lighten(@mainColour, 20%); }
h4 { color: lighten(@mainColour, 30%); }
h5 { color: lighten(@mainColour, 40%); }

Example 3: Computing container width

Container width
We can also use variables and arithmetic to compute the width of a container element to allow for border width and padding:
@outerWidth: 960px;
@borderWidth: 10px;
@padding: 10px;

#container {
  width: @outerWidth - ( @borderWidth + @padding ) * 2;
  border: @borderWidth solid #999;
  padding: @padding;
} 

Grouping stuff using namespaces

You can group variables and mixins under a namespace to keep them separate from other rulesets. This can be handy if you have a lot of LESS rules or include multiple LESS stylesheets, and you want to avoid naming clashes.
To create a namespace, just wrap your rules in a new id selector:

#myNamespace {
  .selector1 { ... }
  #selector2 { ... }
}
Then you can reference the rules in the namespace using the child selector, >:

#myNamespace > .selector1;
#myNamespace > #selector2;
For example, let's encapsulate our container width example from the last section in a namespace called #articlePage:
#articlePage {

  @outerWidth: 960px;
  @borderWidth: 10px;
  @padding: 10px;

  #containerStyle {
    width: @outerWidth - ( @borderWidth + @padding ) * 2;
    border: @borderWidth solid #999;
    padding: @padding;
  }

}
We can now mix the entire #containerStyle ruleset into a #container rule to style our actual container, as follows:
#container { 
  #articlePage > #containerStyle;
}
How's that for powerful!

CSS and LESS comments

You can write comments in two different ways using LESS. Regular CSS comments show up in the CSS output produced by the LESS compiler:

/* This comment will appear in the compiled CSS */
You can also use // to create single-line LESS comments. These are removed by the LESS compiler:

// This comment will not appear in the compiled CSS

Importing other LESS and CSS files

If your LESS stylesheet grows very large then you might want to split it into several .less files. You can then import the individual .less files into a main stylesheet using the @import directive:

@import "common.less";
@import "forums.less";
If you want to import a regular CSS file without running it through the LESS compiler, just make sure your file has a .css extension:

@import "standard.css";  // This file won't be parsed by LESS

Escaping stuff with the e() function

The e() function lets you escape a value so that it's passed straight through to the compiled CSS, without being parsed by the LESS compiler. This can be handy when working with non-standard CSS that LESS doesn't understand:

body {
  filter: e("progid:DXImageTransform.Microsoft.gradient(startColorstr='#aaaaaa', endColorstr='#666666')");
}
This will produce:

body {
  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#aaaaaa', endColorstr='#666666');
}

Pre-compiling LESS code into CSS

Blocks
The one obvious drawback with LESS is that it requires JavaScript to be enabled in the user's browser. If JavaScript is turned off — or the browser can't run JavaScript — then the resulting page will look pretty messy!
Even for browsers that do run JavaScript, there's a slight overhead associated with downloading and running the less.js file.
Because of these issues, you may want to use less.js purely for developing your site. When putting the site live, you can pre-compile your LESS code into a regular CSS stylesheet, which you then serve on your live site instead of the LESS code.
Here are some ways to pre-compile LESS into CSS:
  • Run less.js using Node.js
    You can run the less.js script outside the browser by using the Node.js JavaScript framework. See the relevant section in the LESS documentation for instructions.
  • Use lessphp
    lessphp is an implementation of the LESS compiler written in PHP. You can run it manually to create a CSS file as needed, or you can set it up on your server to compile as required whenever a page is requested (see the documentation for details).
    lessphp's syntax has a few differences from regular LESS, including abstract blocks, a semicolon instead of a comma as the mixin argument separator, and (at the time of writing) no support for the colour functions.
  • Use an online compiler
    If you just want to compile some LESS code quickly without installing a compiler, you can use an online compiler. The lessphp site has an online version you can use. There's also OnLess.
  • Less.app (for Mac users)
    If you're a Mac user, a great free tool is Less.app. This application automatically watches your LESS stylesheets and, whenever you change them, it auto-compiles them into CSS files ready for your website to use. Nice!
Make Your CSS Coding Easier with LESS : LESS Is More Make Your CSS Coding Easier with LESS : LESS Is More Reviewed by JohnBlogger on 5:03 PM Rating: 5

No comments: