CSS was a breakthrough for its time: with one file, we could change an entire site’s look and feel. Its beauty and power lied in that we didn’t have to repeat ourselves. But these days, it seems like we need a CSS for CSS! Developers often have to copy and paste colors, vendor prefixes, and numerous useful styles across their code. Wouldn’t it be great if we could cleanup this mess? Well thankfully we can, with the power of LESS!
What is LESS?
LESS is a dynamic language for generating CSS, allowing us to use variables, operations, functions and even javascript to make our stylesheets much more manageable and intelligent. It’s a superset of CSS, so it extends the basic CSS syntax with more powerful features. This means your existing stylesheets are already valid LESS code, making for an easy learning curve!
With such powerful features, writing clean and maintainable CSS code becomes a joy instead of a chore. Sound exciting? Then let’s dive into an example:
What about SASS?
At the latest UW Web Council, Dale Sande gave a presentation on SASS, a similar language that’s proven popular within the Ruby community. As far as the basics go, LESS and SASS are nearly identical, so we’ll focus on LESS as web designers tend to favor its easy setup and familiar syntax. However I encourage you to learn about SASS as well, as both languages have their pros and cons.
Setting it Up
For this example, we’ll cover a few of LESS’s features to give you a taste of what it can do as we create some button styles. We’ll begin with a site that already has some basic CSS. To start using LESS, we’ll have to do a bit of preparation:
Loading the Script
There are two ways to use LESS: by loading some javascript on your site, or compiling LESS beforehand and using the output CSS file. For this introduction, we’ll go the javascript route as it’s easier to pickup (I explain the compiler route in the footnotes). To load the script, we grab the latest version of LESS from the LESS website and then load it in index.html’s <head> tag:
<script src="less.min.js" type="text/javascript"></script>
Converting Your CSS
Next, we need to convert our CSS file to LESS. Now this part is tricky, so follow along carefully:
- Rename style.css to style.less
- You’re done!
Once we’ve got that down, we need to update our <link> tag so that LESS can detect it. The main difference is the filename and rel attribute:
<link rel="stylesheet/less" type="text/css" href="style.less"> <script src="less.min.js" type="text/javascript"></script>
Note that we load the LESS file before the javascript, otherwise the compiler won’t catch it. Now that our LESS is set up, we can start writing some code!
Cleaning Up the Mess
Nested Rules
Our freshly converted stylesheet already has some styles defined using good ol’ CSS:
p { font-size: 12px; } p a { color: #22F; } button { background-color: #DDD; border: 1px solid #555; -webkit-border-radius: 5px; -moz-border-radius: 5px; -ms-border-radius: 5px; -o-border-radius: 5px; border-radius: 5px; } button:hover { background-color: #CCC; }
It’s only 20 lines, and already there’s plenty of repetition—so let’s clean it up! First off,
using LESS, we can nest our selectors so we don’t have to repeat them.
Here’s what our code looks like after nesting:
p { font-size: 12px; a { color: #22F; } } button { background-color: #DDD; border: 1px solid #555; -webkit-border-radius: 5px; -moz-border-radius: 5px; -ms-border-radius: 5px; -o-border-radius: 5px; border-radius: 5px; &:hover { background-color: #CCC; } }
Now isn’t that nicer? We’re getting the same CSS output with less lines of code, and we’ve also made it easier to see how our styles are related to each other.
Variables
One of LESS’s killer features is the ability to define variables. LESS variables are preceded with an @ symbol, and are defined like so: @variable: definition. Let’s set a variable for our button’s background color:
button { @buttonColor: #DDD; background-color: @buttonColor; border: 1px solid #555; -webkit-border-radius: 5px; -moz-border-radius: 5px; -ms-border-radius: 5px; -o-border-radius: 5px; border-radius: 5px; &:hover { background-color: #CCC; } }
Color Functions
Now that we have @buttonColor defined, we can use LESS’s built-in color functions to clarify that the border should be a shade darker than the background, and the background should darken on hover:
button { @buttonColor: #DDD; background-color: @buttonColor; border: 1px solid darken(@buttonColor, 20%); -webkit-border-radius: 5px; -moz-border-radius: 5px; -ms-border-radius: 5px; -o-border-radius: 5px; border-radius: 5px; &:hover { background-color: darken(@buttonColor, 10%); } }
Isn’t that awesome? Now if we decided to change @buttonColor, the border-color and :hover styles will update accordingly, saving us time and the headache of manipulating colors.
Mix-ins
The darken() function we used is built into LESS, but we can also define our own custom functions! LESS calls them “mix-ins”, and they’re very simple to write. Let’s write a mix-in for generating border radius vendor prefixes:
.border-radius(@radius) { -webkit-border-radius: @radius; -moz-border-radius: @radius; -ms-border-radius: @radius; -o-border-radius: @radius; border-radius: @radius; }
Once that’s defined in our LESS file, we can then call it within our button style like so:
button { @buttonColor: #DDD; background-color: @buttonColor; border: 1px solid darken(@buttonColor, 20%); .border-radius(5px); &:hover { background-color: darken(@buttonColor, 10%); } }
Isn’t that snazzy? Our style is a lot more readable, and we no longer have to write those awful vendor prefixes!
Advanced Mix-ins
Now that we’ve defined our default button style, it would be nice to make a variation of it for a primary action and a dangerous action. We can start by housing the button’s color styles within a mix-in:
@defaultButtonColor: #DDD; .buttonColors(@buttonColor: @defaultButtonColor) { background-color: @buttonColor; border: 1px solid darken(@buttonColor, 20%); &:hover { background-color: darken(@buttonColor, 10%); } }
Note that we’ve set the mix-in to use @defaultButtonColor by default. This means that calling the mix-in with no parameters will give us the default button style:
button { .buttonColors(); .border-radius(5px); }
Next we’ll want to define our colors. We want our primary-action button to have a blue color, and our dangerous-action button to have a red color:
@defaultButtonColor: #DDD; @primaryAction: #99F; @dangerousAction: #F55;
Then, we use the .buttonColors() mix-in to create our new styles with only 6 lines of code!
button.primary { .buttonColors(@primaryAction); } button.dangerous { .buttonColors(@dangerousAction); }
As you can see, mix-ins are a powerful feature that allow us to define common styles and patterns throughout our CSS. With our .buttonColor() mix-in, defining new button styles will be a cinch!
Taking it Further
Hopefully this tutorial has given you a taste of the powerful capabilities of LESS—and we’ve only scratched the surface! To learn more, I highly encourage visiting the LESS homepage which goes into each feature in more detail. Also, please leave a comment if you have questions or want to see more articles like this on the UX blog!
Footnotes
Compiling
If you’re interested in using LESS within a production environment, I highly encourage compiling the files into CSS before serving them on your site. Compiling will combine all of your LESS files into a single, minified CSS file which can be much faster than relying on client-side javascript compilation. This used to be a bit complicated, but thankfully there are stellar applications out there for performing the task:
- For Mac users, I highly recommend LESS.app, a free compiler developed by Bryan Jones that automatically compiles every time you save a LESS file. And if you find it snazzy, definitely take a look at CodeKit, which takes the concept further with more languages and impressive features.
- For Windows users, there’s WinLESS, which is essentially a clone of the Mac app.
- If either of those don’t float your boat, check out the official list of GUI compilers on GitHub.
Further Reading
Check out these sites for more awesome LESS:

This article was fantastic. I’d like to see more articles by this author on the UX blog.
Thanks for the intro, I’ve heard about LESS but this is my first time seeing it.
Yes, great work, Gavin! I have been to a few LESS sessions at various things over the past year or so, and this is what made it finally click for me — thanks!
Now to figure out how to implement it in my team …
Super useful. Thanks for the post, Gavin!
Great article Gavin! I’m planning on sharing this with my INFO 343 course on Web Technologies including CSS and JavaScript. I think you’ll enjoy this great extension of CSS!
good work and good examples….