3.04.2012

Using LESS to make CSS suck less

The days before CSS were bleak days for web programmers. Anyone remember using spacer.gif or the layer tag? So, you ask, what could suck about CSS? It brought us so many wonderful things and made styling and maintaining styles across sites so much easier. Well, it isn’t that CSS itself sucks, per se, it’s that CSS could suck less than it currently does.

For developers who use high-level development languages (expecially object oriented languages) probably cringe at the sheer amount of repeated code in vanilla CSS files. Nesting style rules can be a tediously boring task, particularly when working with a complex document layout. Even worse, major layout changes generally means major re-writing of large chunks of CSS. There has got to be a better way!

LESS to the rescue

LESS is a dynamic stylesheet language. It allows you to work with CSS in a more elegant, programmatic way. It introduces the concepts of variables and functions to CSS in a way that will amaze you. Now, for you non-programmers out there, don’t be deterred. While LESS does use some basic programming concepts to work it’s magic it is by no means a full fledged programming language. In fact, if you already know CSS, you already know how to use LESS. So, are you ready to get your CSS world rocked? Then without further adieu, let’s get into the nitty gritty.

Firstly, go download the LESS javascript library here. You’ll probably want to make a folder to contain any working files you create during this post so do that and drop the LESS library file into it. This file will be included into your HTML file later on.

Second, create two files in the folder you created in step one called index.html and styles.less. You’ll want to use a code editor for this but any text editor that can save HTML and text files will do. Open the index.html file and paste the following code (remember to replace the script tag source to match the file you downloaded as you might be using a different version than the one I’ve used here):

<!DOCTYPE HTML>
<html lang="en-US">
<head>
    <meta charset="UTF-8">
    <title>Using LESS to make CSS suck less</title>
    <link rel="stylesheet/less" type="text/css" href="styles.less">
    <script type="text/javascript" src="less-1.2.2.min.js"></script>
</head>
<body>

</body>
</html>

BOOM! You’re using LESS. Albeit, this isn’t a very exciting example since but it does illustrate how simple using LESS in your projects can be.

Let’s dive right in and look at the one of the more useful aspects of LESS development … variables. We’re going to define a color cheme for this example site. We will have a site background, a headline color, a link color, and some colors for navigation states. We’ll also use a specific, default color for text. Here we go.

First, open up styles.less in your text editor. Let’s enter the following code:

@background:    #556354;
@headline:      #495450;
@links  :       #E58F0D;
@nav_inactive:  #8C948A;
@nav_active:    #42423F;
@text:          #333333;

Now, I know you’re looking at that and saying Wha? What’s with all those @ symbols? Well, I’ll show you. Add the following code below:

body,html {
    background: @background;
    color:          @text;
}

h1, h2, h3, h4, h5, h6 {
    color:  @headline;
}

a {
    color: @links;
}

#nav {
    li {
        a {
            color: @nav_inactive
        }

        a.active {
            color: @nav_active;
        }
    }
}

What this is basically doing is using the color variables we set in the first few lines of code as the color values for each of the style declarations above. This allows you to reuse the color values wherever you see fit. Want to add a border that’s the same color as the headlines? Just use @headline as the border color declaration and you’re all set. Want to change that color? Just change the value that @headline was set to and anywhere that variable is used the color will be changed automagically.

Did you see that weird nested declaration for #nav? I slipped that one in on you. That is an example of what I consider to be the most powerful aspect of working with LESS … nested declarations. The code above will compile as the following CSS:

body, html {
  background: #556354;
  color: #333333;
}
h1,h2,h3,h4,h5,h6 {
  color: #495450;
}
a {
  color: #e58f0d;
}
#nav li a {
  color: #8c948a;
}
#nav li a.active {
  color: #42423f;
}

How cool is that? What LESS’s nested declarations do is allow the developer to model his LESS code after his document’s structure without having to write the tedious and repetitive code of nested style declarations. While it doesn’t seem like it’s saving much in this simple example, imagine the complicated layouts you’ve created before and how frustrating it was to maintain proper cascading when styling items. It also allows the reuse of classes within nested declarations without worrying that you’ve used that same class outside of the current declaration.

Getting back to variables, there is another type of variable you can use in LESS called a mixin. This allows you to include a bunch of properties from one ruleset to another. For example, say we want to have a standardized bottom border for any number of elements. You can do something like this:

.bottom_border {
    border-bottom: 1px solid @links;
    margin-bottom: 3px;
}

Then this can be used anywhere you want. Like so:

h1 {
    .bottom_border;
}

Which will compile as:

h1 {
  border-bottom: 1px solid #e58f0d;
  margin-bottom: 3px;
}

You can even use parametric mixins that can take values. For example, if we wanted to allow for variable width borders within our .bottom_border mixin we can modify it like so:

/* LESS Parametric Mixin */
.bottom_border(@width: 1px) {
    border-bottom: @width solid @links;
    margin-bottom: 3px;
}

/* H1 Tag Passing new Border Width */
h1 {
    .bottom_border(3px);
}

This essentially says that I want my h1 tag to render with a 3 pixel bottom border instead of the default 1 pixel width. Amazing! There’s plenty more things you can do with variables and mixins and, if they were all that LESS did, it would be worth learning. There are many more things you can do with LESS but they are a bit more programmy (I just made that up) and will be covered in later posts.

There’s one last thing I want to cover before signing off. I know some of you developers out there are saying to yourselves Oh great, another Javascript library that I need to include or Wait a minute. This guy wants me to have my CSS depend on Javascript? No graceful degradation! No WAY!!. Well, not to worry, LESS has you covered. LESS was originally developed using the Ruby language and can be used on the command line (UNIX geeks unite!) to compile LESS to CSS manually. The current implementation was rewritten in Javascript for two reasons:

  1. It’s approximately 10x faster than the Ruby version.
  2. It can be used more easily in a development environment.

I know, I know. Manual compilation just begs for mistakes and human error. That’s where the wonderful LESS tool makes this process a breeze. This tool was developed by Bryan Jones and it is a slick one. Here’s what to do.

  1. Download the app
  2. Drop it in your Applications folder.
  3. Launch the app.
  4. Click the plus button to add your .less file to the compiler.
  5. Right click on your .less file and click on Set CSS Output Path. For our example project this can be the root directory or, for more complex projects, your CSS directory, wherever that may be.

Now, when you save your .less file it will be automatically converted to a CSS file. This means you don’t have to include the LESS Javascript library and can instead reference the styles.css file (or whatever your file might have been named) that was generated by the compiler. This means no more depending on Javascript to parse your LESS on the fly which makes it great for production environments.

Hopefully you’ve been able to see the power, speed and efficiency that LESS development can bring to your CSS life. Trust me, use it on your next project and tell me if it doesn’t make CSS suck less. If it doesn’t, you’re doing it wrong.

No comments:

Post a Comment

share

Bookmark and Share