CSS: A Little More on Less

Suck in a big lungful of sweet air, fellow CSS monkeys, because 2010 is a good time! After years of stuttering progress, scheming browser-makers, hidden agendas, and petrified standards bodies, things seem to be finally moving in the right direction.

Why? Well, here’s an overview:

  • Lots of the most useful CSS3 properties are now supported by all the major non-IE browsers — although admittedly they do often require proprietary code (e.g. -moz or -webkit).
  • New CSS3 properties are being introduced to each browser update.
  • Though clearly IE8 doesn’t deal well with CSS3, it at least tends to render our plain CSS2 in a predictable manner.
  • Although I wouldn’t rule out Microsoft’s ability to snatch fail from the jaws of victory (shout-out to the MS Outlook team), all the signs are
    promising for IE9.

Good times indeed.

There are some niggles, though. Currently CSS3 can be mighty ungainly to work with. Let’s take a typical CSS3 property such as “box-shadow.”

For Opera (and with any luck IE9), we need to use the standard CSS3 syntax:

box-shadow: 1px 1px 8px #999999

Safari and Chrome currently still require their own version of that code:

-webkit-box-shadow: 1px 1px 8px #999999

Ol’ Firefox plays along nicely — just as long as you give it what it wants.

-moz-box-shadow: 1px 1px 8px #999999

Although this all works like charm in each of those browsers, it’s a pain in the backside to manage. If you want to tweak the shadow color or adjust the blur, you need to edit your CSS in three places.

Quite apart from being tiresome, this gives you more places to make mistakes. There should be a way to “write once, use everywhere” — and, of course, there is.

LESSLast year, Raena introduced us to us how to a system called LESS. The concept behind LESS is to allow you to set CSS variables that can then be used throughout your code.

LESS was developed as Ruby-based solution, which is awesome if you’re a Ruby user — but not so useful if you’re not. In the intervening time, we’ve seen the development of PHP and .NET versions of LESS.

Ok, that’s great, but what if you want to get a feel for what LESS can do without installing code or committing to a server-side technology? Happily, it can be done.

Google Code now allows you to link and run a JavaScript version of LESS directly from its servers. Here’s a quick demo using the example I cited above:

1). Start a new CSS file and cut and paste your CSS rule into it:

.content {
   box-shadow: 1px 1px 8px #999999;
   -webkit-box-shadow: 1px 1px 8px #999999;
   -moz-box-shadow: 1px 1px 8px #999999;
  }

2). Save that file as “style.less

3). Next, we’re going to create four new variables at the top of that file. We declare them with an @ at the start, but they can be called anything you like. I’ve tried to make my variable names plain and sensible:


  @box-x: 1px;
  @box-y: 1px;
  @box-blur: 8px;
  @box-col: #999999;

.content {
   box-shadow: 1px 1px 8px #999999;
   -webkit-box-shadow: 1px 1px 8px #999999;
   -moz-box-shadow: 1px 1px 8px #999999;
  }

I’ve also given each variable a value.

4). Now we need to edit our CSS values to replace them with our new CSS variables. That should give you something like this:


 @box-x: 1px;
  @box-y: 1px;
  @box-blur: 8px;
  @box-col: #999999; 

.content {
 box-shadow:@box-x @box-y @box-blur @box-color;
 -webkit-box-shadow: @box-x @box-y @box-blur @box-color;
 -moz-box-shadow: @box-x @box-y @box-blur @box-color;
 

5). We’ll next need to link this file from the head of our HTML document. At first glance this may look like a regular LINK tag, but don’t overlook the unusual REL attribute with a value of stylesheet/less:

<link rel="stylesheet/less" href="style.less" type="text/css" />

6). Finally, we have to attach the code that does all the grunt work — the LESS JavaScript library:

<script src="http://lesscss.googlecode.com/files/less-1.0.18.min.js"></script>

I’ve deliberately left this step till last, because the order in which these files are loaded IS important. This LESS library file must be loaded after your CSS (i.e your 'style.less' document).

LESS demoHere’s a simple demo showing the code in action. Each one of our variables is automatically inserted into each CSS rule on the fly.

Now if we need to tweak the color of our box-shadow, a single change to the @box-color variable at the top of our style document will change it across the entire document.

And this is really just scratching the surface of LESS. As Raena’s original post explains, LESS lets you:

  • calculate your columns width and margins as a percentage of your body width (e.g. width: @bodywidth/6)
  • nest CSS rules within other CSS rules to generate new child rules
  • group commonly used CSS snippets into reuseable “mix-ins”

It’s all exciting stuff to play with.

But Are There Any Catches?

Of course, there is one obvious issue with this solution. If a user doesn’t have JavaScript enabled, none of these styles will be rendered.

As such, it might make some sense to keep all your primary styles in a garden-variety stylesheet, and then breaking out our CSS3 finery into a LESS stylesheet.

Moreover, if you decide LESS is the way forward for you (or similar technologies like Sass and CSS Scaffold), you might need to look at server-based solutions.

Nevertheless, if you’re looking for an easy way to dip your toe into the water, who could ask for.. more?

From Design View #74

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • http://www.jonathanpenny.co.uk jonpenny

    I fail to see how this is less exactly? Why not just have a CSS property called .box_shadow then style it like this…

    .box_shadow {
    box-shadow: 1px 1px 8px #999999;
    -webkit-box-shadow: 1px 1px 8px #999999;
    -moz-box-shadow: 1px 1px 8px #999999;
    }

    Then just add a class of .box_shadow to all the DIV’s you want to have a box shadow. Seems a lot easier to me. And it works with no JavaScript.

    • Montpellier Interactive

      Good idea jonpenny

    • http://logicearth.wordpress.com logic_earth

      A better approach is to use Less Mixins instead of applying the class to whatever.
      .rounded_corners (@radius: 5px) {
      -moz-border-radius: @radius;
      -webkit-border-radius: @radius;
      border-radius: @radius;
      }
      #header { .rounded_corners; }
      #footer { .rounded_corners(10px); }

      • http://www.myspace.com/pas_non pas_non

        WHAT IS THIS?? i’ve never seen or heard of it before and it’s totally blowing my mind :D

    • http://www.visual28.com visual28

      My thoughts exactly. Work smarter not harder. OOCSS FTW

    • http://galengidman.com/ fendeanson

      I say the less classes you have in your HTML the better. Less seems like a good idea to me, especially the mix-ins.

  • mathieuf

    The concept of variables in CSS has been sorely lacking. Any chance the standards committees are moving to support this in a future version? Or browsers doing a run-around?

    I would like to use the Google solution but am limited by rules about third-party code in my organization. The JavaScript is also an issue, although most browsers hitting our site do have it enabled. A server-side solution seems best. (Does this affect caching of the CSS by the browser?)

    @jonpenny: Think beyond the one example. When the designer wants to make some minor color adjustments, I want to change this in one place, not in the multiple places it might occur throughout my CSS files.

    • http://www.jonathanpenny.co.uk jonpenny

      I’ll stick with my method thanks. It’s simple and it’s worked for years. No relying on JavaScript or server side code. Simple, clean CSS that works. If it’s not broken, don’t try and fix it.

  • http://www.sitepoint.com AlexW

    @jonpenny: The example is presenting the simplest demo, but in a real-world scenario a typical CSS variable like a background-color or border-radius might be referenced more than a dozen times through-out your stylesheet.

    Integrating your CSS cleverly helps, but combining rules just because they have the same green doesn’t always make sense if they don’t share other properties.

    @mathieuf: I don’t have a lot of faith in standards bodies to get this sort of thing moving. Browser makers could make it happen in new browsers without too much fuss, but backward compatibility seems like a hurdle to me.

    If IE8 can’t do rounded corners, no biggie. You get square corners like you always did. If if your background color completely fails in IE8, that’s gonna be a problem for most people.

    Short of using a JavaScript-based solution like the one above for older browsers — basically filling in the gaps with JS like PIE does — I’m not sure how else we’d get around that issue.

    • http://www.jonathanpenny.co.uk jonpenny

      If a client/designer comes back to me with the need for a background colour to be changed I find the line number, use the “go to line-number” shortcut in my text editor, change the colour and upload. Takes seconds. I can understand the idea behind it but I personally don’t think it speeds up my coding time or helps productivity in any way. I also don’t think it is “less”.

      Also the fact it relies on JavaScript makes it a big no for me. I’ve written my CSS as normal CSS for years and don’t see the need to change it with a method like this.

      That’s my humble opinion anyway.

  • http://www.yacare.fr McBenny

    Looks like a lot more to me. Linking a JS file and a separate style sheet is to much for me.
    As I don’t use CDN, I prefer a server-side solution : my CSS file is something like this : style.css.php => I can use PHP into my file.
    I have a PHP variable like this :
    <?php
    $prefixCSS=stristr($_SERVER['HTTP_USER_AGENT'],’AppleWebKit’)?’-webkit-’:(stristr($_SERVER['HTTP_USER_AGENT'],’Gecko/’)?’-moz-’:null);
    ?>
    Which gives $prefixCSS=’-moz-’ if I’m in front of a Mozilla-based browser, $prefixCSS=’-webkit-’ in front of a webkit-based browser and finally nothing in front of anything else.
    Then, in my CSS file I write this :
    #anyElt {
    <?php echo $prefixCSS; ?>border-radius:5px;
    }
    This results in the only result needed for the browser.
    I can set the cache of the file so that the browser doesn’t always download it on each page.
    When a browser suddenly understands things as it should (for example webkit supports CSS3 declarations, without its prefix), I just have to change my PHP variable so that in front of a webkit-based browser my variable becomes null.
    As the browsers will progress, I will only reduce my “hack”.
    The only problem with this technique is if you use a Content Delivery Network : the first browser to ask for the CSS file will “create” it on the CDN. If this browser is Mozilla-based, it will generate a CSS file that will not suite other types of browsers.
    .
    For the problem of colors discussed earlier, PHP solves the problem : I also use PHP variables for colors :
    #anyElt {
    border: 1px solid <?php echo $mainColor; ?>;
    color: <?php echo $textColor; ?>;
    }
    This way, you have a set of PHP variables that are invoked throughout your entire CSS file and you can adjust any color everywhere it happens in a single place.

    • the.peregrine

      A beautifully elegant solution! Thanks for sharing.

  • http://r.je TomB

    The idea of CSS variables is a good one and should be part of the standard.

    The problem I have with LESS and other solutions is that it’s a custom syntax to learn which differs between all the implementations.

    By relying on 3rd party code with custom syntax you open yourself to several problems:
    -Any other developer who needs to edit the code needs to know the new syntax
    -Either the client needs to enable javascript or you reduce code portability by making it only run on servers which support the underlying technology used.

    I like the idea, but practically I don’t think I’d like to commit to a specific implementation.

  • the.peregrine

    I agree with those who say LESS is not less at all. This is fundamentally a code-maintenance issue that can be handled with a well-managed workflow. Why rely on any external scripting language (whether PHP, .NET or javascript) when the solution is almost invariably going to be as simple as search/replace? Every coding environment has that functionality.
    Perhaps more than any other coding, the key to robust CSS is uncompromising simplicity — even if you have to throw in an occasional bone for that mangy Microsoft dog. The solution offered by LESS is more complex than the problem it’s designed to solve.