Dynamic CSS3 Buttons with LESS
July 4th, 2010
There’s been a lot of buzz surrounding CSS3 buttons – including some really great tutorials. The concept behind a basic button, however, is pretty simple:
- Apply a subtle background gradient
- Add some rounded corners
- Add text shadows – optionally
- Add a thin border – optionally
- Add a box shadow – optionally
- Repeat this process for active and hover states
For sure, making good buttons means doing these steps well. But programmatically, this is pretty damn simple. The difficultly lies in design not code.
With that in mind, let’s look at how we might use a CSS abstraction language, like LESS, to boil these steps down and make our button code super flexible. But first, let’s take a look at CSS abstraction languages more generally.
What’s a CSS abstraction language?
An abstraction language is a wrapper that adds powerful functionally to the standard CSS language. Have you ever wanted to set a variable in your stylesheet or do some math? Abstraction languages make this possible.
Now, if you’re like me, you might be thinking: “If I need to do multiplication in a stylesheet something’s gone terribly wrong.” Keep reading. Maybe you’ll change your mind.
How do I use a CSS abstraction language?
Normally, abstraction languages require a supporting back-end language. This supporting language parses your abstracted code and generates normal, static stylesheets at runtime. Ruby, for example, does exactly this to turn SASS into CSS.
That’s cool, but for most projects we don’t need a powerful back-end framework. And there’s certainly no reason start using one just to make your stylesheets more dynamic. This means, by and large, abstraction languages just aren’t viable except in large, complicated projects.
But LESS is about to change all that. Alexis Sellier has recently developed a pure JavaScript implementation. This means no back-end language is required. Just follow these simple steps:
- Give your stylesheet a mime type of .less rather than .css
- Add an attribute of rel="stylesheet/less" rather than rel="stylesheet"
- Include the less.js script below all stylesheets in your header.
With that finished, your header should include something like:
<link rel="stylesheet/less" href="buttons.less" type="text/css" charset="utf-8" >
<script src="less-1.0.30.min.js" type="text/javascript" charset="utf-8"></script>
And now we have access to some pretty awesome features. Like setting variables and performing operations:
@pagewrap_width: 970px
@accent_color: #2BBF26;
section {
@pagewrap_width - 300px
color: @accent_color - #f0f0f0;
}
And that’s just a few of the awesome features. I encourage you to checkout the details and documentation.
How can we use this to make better buttons?
1 Get a nice looking button.
Making a nice button can be tricky, so I recommend using the code posted in one of these excellent tutorials. But if you’d rather roll your own, I suggest this dead simple button making tool.
Whatever your method, just get some CSS and paste it into your LESS equipped stylesheet. In this example, I’ll be using this code:
/* styles for button color */
.button {
color: #fef4e9;
border: solid 1px #da7c0c;
background: #f78d1d;
background: -webkit-gradient(linear, left top, left bottom, from(#faa51a), to(#f47a20));
background: -moz-linear-gradient(top, #faa51a, #f47a20);
}
.button:hover {
background: #f47c20;
background: -webkit-gradient(linear, left top, left bottom, from(#f88e11), to(#f06015));
background: -moz-linear-gradient(top, #f88e11, #f06015);
}
.button:active {
background: -webkit-gradient(linear, left top, left bottom, from(#f47a20), to(#faa51a));
background: -moz-linear-gradient(top, #f47a20, #faa51a);
}
/* basic styles for button size, padding, etc. */
.button {
display: inline-block;
outline: none;
cursor: pointer;
text-align: center;
text-decoration: none;
font-size: @font_size;
line-height: 100%;
font-family: Helvetica, Verdana, Arial, sans-serif;
padding: .55em 2em .55em;
text-shadow: 0 1px 1px rgba(0,0,0,.3);
-webkit-border-radius: 0.5em;
-moz-border-radius: 0.5em;
border-radius: 0.5em;
-webkit-box-shadow: 0 1px 2px rgba(0,0,0,.2);
-moz-box-shadow: 0 1px 2px rgba(0,0,0,.2);
box-shadow: 0 1px 2px rgba(0,0,0,.2);
}
.button:hover {
text-decoration: none;
}
.button:active {
position: relative;
top: 1px;
}
And our buttons will look like:

2 Extract the important stuff into variables.
That’s a lot of CSS but let’s focus on what actually matters: font color, border radius, border color, padding, and background gradients.
Let’s move these values into variables. It’s a good convention to place them at the top of your stylesheet like so:
/* basic button variables */
@background_color: #f78d1d;
@hover_background_color: #f47c20;
@border_radius: 0.5em;
@font_size: 14px;
@font_color: #fef4e9;
@button_padding: 0.55em 2em;
@border_color: #da7c0c;
/* background color gradients for each state */
@normal_background_top: #faa51a;
@normal_background_bottom: #f47a20;
@hover_background_top: #f88e11;
@hover_background_bottom: #f06015;
@active_background_top: #f47a20;
@active_background_bottom: #faa51a;
/* ...previous css with original values substituted for variables... */
Now, already that’s a nice improvement. We can easily make changes to our button styles without having to wade through all that CSS. Want rounder corners? Just increase @border_radius.
3 Make a good thing better with high school math.
While we’ve made an improvement, that still feels like too many configuration options for a simple button. Wouldn’t it be nice, for example, if we didn’t have to worry with all those color variations (i.e. border color, background colors, gradients, etc). It would be much better if we could consolidate all those values into a single variable (e.g. @button_color).
Let’s do just that. First, let’s change @background_color to @button_color. We’ll hold this value constant and set all of our other color-related values relative to @button_color. This means we’ll be able to alter one variable — @button_color — and changes will automatically cascade through related variables.
In case you’re confused, I’ll break it down a bit so you can see what’s going on. We’re just doing some simple math with hexcodes:
/* we've already set these variables */
@background_color: #f78d1d;
@border_color: #da7c0c;
/* if we know that: */
@button_color - @border_color = #1D1111
/* then high school algebra says: */
@border_color = @button_color - #1D1111
So we can use this concept to set all our color values relative @button_color. Now our configuration options are looking much leaner:
/* button configuration options */
@button_color: #f78d1d;
@border_radius: 0.5em;
@font_size: 14px;
@font_color: #fef4e9;
@button_padding: 0.55em 2em;
/* color variables set relative to @button_color.
You probably don't need to change these. */
@hover_background_color: @button_color - #031100;
@border_color: @button_color - #1D1111;
@normal_background_top: @button_color + #031800;
@normal_background_bottom: @normal_background_top - #062B00;
@hover_background_top: @button_color + #010100;
@hover_background_bottom: @hover_background_top - #082E08;
@active_background_top: @normal_background_bottom;
@active_background_bottom: @normal_background_top;
/* ...previous css with original values substituted for variables... */
So now we only need to concern ourselves with five clearly named variables. And we can easily change our style to suit different themes. Change the value of @button_color to #ffb515 and you get yellow buttons complete with CCS3 gradients:

Or change @button_color to #2daebf and @font_size to 22px:

You get the idea. Changing styles couldn’t be easier.
But this is about more than just buttons.
This is just a trivial example of how LESS can make our stylesheets more dynamic. Imagine, for example, WordPress themes where non-developers could alter the entire color scheme by changing a single variable. Or tweak the layout through something like @sidebar_width.
When done well, layouts could even feel a bit like jQuery plugins. Just download the files, change a few configuration options, and you’re ready to roll. This would be especially useful for stylesheets that aren’t too application specific — like wireframe layouts or admin/cms interfaces.
Maybe designers will even start open-sourcing layouts the way developers share plugins? Maybe.
On the subject of open-sourcing layouts, make sure you check out Compass (http://compass-style.org). One of its main goals is to provide a framework for distributing reusable styles (using Sass, which is better suited to the task than Less due to its greater degree of power). Quite a few extensions have already been created, including one for handling buttons like those you describe (http://github.com/imathis/fancy-buttons).
I would strongly caution against using a client-side stylesheet compiler in production, though. It completely breaks styling for people not using JS, which may or may not be a problem depending on the site. But it’s a large problem for any site that cares about its load speed, as the client-side compilation can take time on the order of an additional HTTP request.
Also, as the lead Sass developer, I contest your claim that it requires a powerful backend framework. With the sass command-line tool, it’s easy to integrate Sass with a static site (even during development using sass –watch).
Reply
@Nathan
I actually prefer SASS to LESS. Not just for the syntax but for the feature set as well.
I wasn’t aware sass –watch worked independent of compass. But, having checked it out, I agree it definitely accomplishes the same thing but with several benefits – especially the reduced performance cost.
For what it’s worth, however, the LESS documentation claims that the performance hit is very negligible. Still, why get JavaScript involved at run time if you can avoid it?
Keep up the good work. I’d love to see more people using SASS outside the ruby community.
…
And for those of you might have no idea what were talking about:
http://nex-3.com/posts/90-auto-compile-sass-files-with-sass-3
July 5th, 2010 Cory Schires
July 5th, 2010
Nathan Weizenbaum[...] Cory Schires — Dynamic CSS3 Buttons with LESS [...]
July 6th, 2010
Dynamic <span class="caps">CSS3</span> Buttons with <span class="caps">LESS</span> | RefreshTheNetIf you install NodeJS you can run less as a compiler offline just as you can with SASS. You may also want to incorporate some more high school math to modify your base colors or use the color functions that come with LESS to make single argument (your base color) button generators. I have been doing this for a bit and may soon release what I have if you are interested.
Reply
July 8th, 2010
Dylan Wreggelsworth[...] Free Tools To Create Different DiagramsCSS3 Typography and Special EffectsApple Navigation with CSS3Dynamic CSS3 Buttons with LESSMinimalistic Slideshow Gallery with jQuery28 Minimalist Movie Posters32 Creative and Clever Sports [...]
July 13th, 2010
Weekly Design News – Resources, Tutorials and Freebies (N.45) - Speckyboy Design MagazineNice tutorial!
Reply
July 22nd, 2010
amprodes