RSS
 

Using the LESS CSS Preprocessor for Smarter Style Sheets

06 Dec

Advertisement in Using the LESS CSS Preprocessor for Smarter Style Sheets
 in Using the LESS CSS Preprocessor for Smarter Style Sheets  in Using the LESS CSS Preprocessor for Smarter Style Sheets  in Using the LESS CSS Preprocessor for Smarter Style Sheets

As a Web designer you’re undoubtedly familiar with CSS, the style sheet language used to format markup on Web pages. CSS itself is extremely simple, consisting of rule sets and declaration blocks—what to style, how to style it—and it does pretty much everything you want, right? Well, not quite.

You see, while the simple design of CSS makes it very accessible to beginners, it also poses limitations on what you can do with it. These limitations, like the inability to set variables or to perform operations, mean that we inevitably end up repeating the same pieces of styling in different places. Not good for following best practices—in this case, sticking to DRY (don’t repeat yourself) for less code and easier maintenance.

Enter the CSS preprocessor. In simple terms, CSS preprocessing is a method of extending the feature set of CSS by first writing the style sheets in a new extended language, then compiling the code to vanilla CSS so that it can be read by Web browsers. Several CSS preprocessors are available today, most notably Sass and LESS.

Less-css in Using the LESS CSS Preprocessor for Smarter Style Sheets

What’s the difference? Sass was designed to both simplify and extend CSS, so things like curly braces were removed from the syntax. LESS was designed to be as close to CSS as possible, so the syntax is identical to your current CSS code. This means you can use it right away with your existing code. Recently, Sass also introduced a CSS-like syntax called SCSS (Sassy CSS) to make migrating easier.

If It Ain’t Broke…?

By now you might be thinking, “So what? Why should I care about these things, and how exactly will they make my life as a Web designer easier?” I’ll get to that in a moment, and I promise it will be worth your time. First, let me clarify the focus of this article.

In this tutorial, I’ll be using LESS to demonstrate how CSS preprocessing can help you code CSS faster. But that doesn’t mean you must use LESS. It’s my tool of choice, but you may find that Sass fits your workflow better, so I suggest giving them both a shot. I’ll talk a bit more about their differences at the end of the article.

I’ll start off by explaining how LESS works and how to install it. After, I’ll list a set of problems that large CSS files pose, one by one, and exactly how you can use LESS to solve them.

Let’s go!

Installing It

There are two parts to any CSS preprocessor: the language and the compiler. The language itself is what you’ll be writing. LESS looks just like CSS, except for a bunch of extra features. The compiler is what turns that LESS code into standard CSS that a Web browser can read and process.

Many different compilers are actually available for LESS, each programmed in a different language. There’s a Ruby Gem, a PHP version, a .NET version, an OS X app and one written in JavaScript. Some of these are platform-specific, like the OS X app. For this tutorial, I recommend the JavaScript version (less.js) because it’s the easiest to get started with.

Using the JavaScript compiler is extremely easy. Simply include the script in your HTML code, and then it will process LESS live as the page loads. We can then include our LESS file just as we would a standard style sheet. Here’s the code to put between the <head> tags of your mark-up:

<link rel="stylesheet/less" href="/stylesheets/main.less" type="text/css" />
<script src="http://lesscss.googlecode.com/files/less-1.0.30.min.js"></script>

Note that I’m referencing the less.js script directly from the Google Code server. With this method, you don’t even have to download the script to use it. The style sheet link goes above the script to ensure it gets loaded and is ready for the preprocessor. Also, make sure that the href value points to the location of your .less file.

That’s it. We can now begin writing LESS code in our .less file. Let’s go ahead and see how LESS makes working with CSS easier.

1. Cleaner Structure With Nesting

In CSS, we write out every rule set separately, which often leads to long selectors that repeat the same stuff over and over. Here’s a typical example:

#header {}
#header #nav {}
#header #nav ul {}
#header #nav ul li {}
#header #nav ul li a {}

LESS allows us to nest rule sets inside other rule sets, as a way to show hierarchy. Let’s rewrite the above example with nesting:

# header {
  #nav {
    ul {
      li {
        a {}
      }
    }
  }
}

I’ve omitted the content from the selectors for simplicity, but you can see how the structure of the code quickly changes. Now you don’t have to repeat selectors over and over again; simply nest the relevant rule set inside another to indicate the hierarchy. It’s also a great way to keep code organized because it groups related items together visually.

Also, if you want to give pseudo-classes this nesting structure, you can do so with the & symbol. Pseudo-classes are things such as :hover, :active and :visited. Your code would look as follows:

a {
  &:hover {}
  &:active {}
  &:visited {}
}

2. Variables For Faster Maintenance

We usually apply a palette of colors across an entire website. Any given color could be used for multiple items and so would be repeated throughout the CSS code. To change the color, you’d have to do a “Find and replace.”

But that’s not quite it. You could also isolate those values into separate rule sets; but with this method, the rule sets would keep growing as you add more colors across the website, leading to bloated selectors. Here’s what I’m talking about:

#header, #sidebar .heading, #sidebar h2, #footer h3, .aside h3 { color: red; }

To make a simple color change, we’re faced with long selectors, all dedicated to that one color. It’s not pretty. LESS allows us to specify variables in one place—such as for brand colors, border lengths, side margins and so on—and then reuse the variables elsewhere in the style sheet. The value of the variable remains stored in one place, though, so making a change is as simple as changing that one line. Variables start with an @ and are written like this:

@brand-color: #4455EE;

#header { background-color: @brand-color; }
#footer { color: @brand-color; }
h3 { color: @brand-color; }

In LESS, variables also have scope, so you could use variables with the same name in various places; when they’re called, the compiler would check for the variable locally first (i.e. is there anything with that name where the declaration is currently nested?), and then move up the hierarchy until it finds it. For example, the following code:

@great-color: #4455EE;

#header {
  @great-color: #EE3322;
  color: @great-color;
}

…compiles to:

#header { color: #EE3322; }

3. Reusing Whole Classes

Variables are great, but we often reuse more than single values. A good example is code that’s different for every browser, like the CSS3 property border-radius. We have to write at least three declarations just to specify it:

-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;

If you use a lot of CSS3, then this sort of repeating code adds up quickly. LESS solves this by allowing us to reuse whole classes simply by referencing them in our rule sets. For example, let’s create a new class for the above border-radius and reuse it in another rule set:

.rounded-corners {
  -webkit-border-radius: 5px;
  -moz-border-radius: 5px;
  border-radius: 5px;
}
#login-box {
  .rounded-corners;
}

Now #login-box will inherit the properties of the rounded-corners class. But what if we want more control over the size of the corners? No problem. We can pass along variables to the “mixin” (these reusable classes are called mixins) to get a more specific outcome. First, we rewrite the original mixin to add the variable we want to manipulate:

.rounded-corners(@radius: 5px) {
  -webkit-border-radius: @radius;
  -moz-border-radius: @radius;
  border-radius: @radius;
}

Now we’ve replaced the values for a variable, and we’ve specified the default value inside the parentheses. To give mixins multiple values, you’ll just need to separate them with a comma. Now, if we want our #login-box to have a border radius of three pixels instead of five, we do this:

#login-box {
  .rounded-corners(3px);
}

4. Operations

Variables let us specify things such as common palettes of colors, but what about relative design elements, like text that’s just a bit lighter than the background, or an inner border that’s one pixel thicker than the outer border?

Rather than add more variables, we can perform operations on existing values with LESS. For example, we can make colors lighter or darker or add values to borders and margins. And when we change the value that these operations depend on, they update accordingly. Take the following:

@base-margin: 25px;
#header { margin-top: @base-margin + 10px; }

This gives the #header element a top margin of 35 pixels. You can, of course, also multiply, divide and subtract, and perform operations on colors like #888 / 4 and #EEE + #111.

5. Namespaces and Accessors

What if you want to group variables or mixins into separate bundles? You can do this by nesting them inside a rule set with an id, like #defaults. Mixins can also be grouped in this way:

#defaults {
  @heading-color: #EE3322;
  .bordered { border: solid 1px #EEE; }
}

Then, to call a variable and a mixin from that particular group, we do this:

h1 {
  color: #defaults[@heading-color];
  #defaults > .bordered;
}

We can even access values of other properties in a given rule set directly, even if they’re not variables. So, to give the sidebar heading the same color as your main h1 heading, you’d write:

h1 { color: red; }

.sidebar_heading { color: h1['color']; }

There’s not much difference between variables and accessors, so use whichever you prefer. Accessors probably make more sense if you will be using the value only once. Variable names can add semantic meaning to the style sheet, so they make more sense when you look at them at a later date.
A couple more things to mention: You can use two slashes, //, for single-line comments. And you can import other LESS files, just as in CSS, with @import:

@import 'typography';
@import 'layout';

To Conclude

I hope by now you’ve got a pretty good idea why CSS preprocessors exist, and how they can make your work easier. The JavaScript version of the LESS compiler, less.js, is of course just one way to use LESS. It’s probably the easiest to get started with, but it also has some downsides, the biggest one being that the compiling takes place live. This isn’t a problem on modern browsers with fast JavaScript engines, but it might work slower on older browsers. Note that less.js actually caches the CSS once it’s processed, so the CSS isn’t regenerated for each user.

To use the generated CSS instead of LESS in your markup, you can compile your files using the various other compilers. If you’re on OS X, I suggest trying out the LESS App, a desktop app that watches your LESS files for changes as you work and automatically compiles them into CSS files when you update them. The Ruby Gem has the same watcher functionality but is trickier to install if you’re not familiar with Ruby (see the official website for details on that). There are also PHP and .NET versions.

Finally, LESS isn’t your only option for a CSS preprocessor. The other popular choice is Sass, but there are still more options to check out, such as xCSS. The advantage of LESS is that it uses existing CSS syntax, so getting started is just a matter of renaming your .css file to .less. This might be a disadvantage if you dislike the CSS syntax and curly braces, in which case Sass would probably be a better choice. There is also the Compass framework available for Sass, which is worth checking out if you go with Sass.

(al) (sp)


© Dmitry Fadeyev for Smashing Magazine, 2010. | Permalink | Post a comment | Add to del.icio.us | Digg this | Stumble on StumbleUpon! | Tweet it! | Submit to Reddit | Forum Smashing Magazine
Post tags: ,

 
 

Tags: , ,