notoriousb1t

Why I use LESS for CSS

You can improve your productivity and your style reuse in web design by using a CSS transpiler. CSS transpilers read in another style language and translate it to CSS. My favorite of these is LESS. It gives you compile-time validation of your stylesheets and a large set of features. You can perform massive theme changes very quickly and in very few lines of code. Here are some of the game changers:

Variables

One of the biggest reasons for a web designer to use LESS is because it allows quick re-theming of an application. Consider the following CSS.

CSS Snippet

    body {
      background-color: white;
      color: #444444;
    }
    .button-primary {
      background-color: #006400;
      color: white;
    }
    a[href] {
      color: #006400;
    }

Imagine that you have to change the color green from #006400 to #008000. At 11 lines of code, this is quite managable. At 2000 lines of CSS across 6 files, it is quite a different story. Let's take a look at a LESS equivalent:

LESS equivalent

    @primaryColor: #006400;
    @primaryContrastColor: white;
    @textColor: #444444;
    body {
        background-color: @primaryContrastColor;
        color: @textColor;
    }
    .button-primary {
        background-color: @primaryColor;
        color: @primaryContrastColor;
    }
    a[href] {
        color: @primaryColor;
    }

Not that much more code, and it is already more managable. If I want to change the primary color of the application, I only have to change it in one place. CTRL + H need not apply.

Mixins

Mixins allow an incredible amount of CSS reuse and can make everything a lot more readable. The syntax for a mixin almost looks like typical CSS. Here is an example of a simple mixin:

Simple Mixin

    .panel() {
        border-radius: 1rem;
        border: solid thin black;
        padding: 1em;
    }

Simple Usage

    fieldset {
        font-size: 0.95em;
        .panel()
    }
    .my-class {
        .panel()
    }

CSS output

    fieldset {
        font-size: 0.95em;
        border-radius: 1rem;
        border: solid thin black;
        padding: 1em;
    }
    .my-class {
        border-radius: 1rem;
        border: solid thin black;
        padding: 1em;
    }

The contents of .panel() are placed in fieldset and in the .my-class class code. I think of mixins as being a list of CSS rules to apply. They are great for creating general styling rules that apply to a bunch of loosely related elements. Using mixins allows you to use the DRY (Don't Repeat Yourself) principle in your stylesheets.

Mixins also make it easier to deal with cross-browser support. For properties with varying support across browsers, you can create a mixin with each vendor prefix. Then you can simply include that mixin instead of littering your CSS with -moz and -webkit.

Vendor Prefixes

    .box-sizing(@type: border-box) {
        -moz-box-sizing: @type;
        -webkit-box-sizing: @type;
        box-sizing: @type;
    }
    .border-box {
        .box-sizing()
    }

This mixin adds the box-sizing property with all vendor prefixes. It is set with a default of border-box. Here is the output CSS:

Output CSS

    .border-box {
      -moz-box-sizing: border-box;
      -webkit-box-sizing: border-box;
      box-sizing: border-box;
    }

Imports

LESS allows your CSS to be split into multiple files and then imports them into a single CSS file. This is a huge boon to organization because no matter how I split up the CSS, it all ends up as one downloadable file. If I wanted, I could create separate .less files for each page, for each component, or organize it by each responsibility. It makes no difference to the browser. Consider the following example:

Importing different files

    @import "variables.less";
    @import "mixins.less";
    body {
        font-size: @baseFontSize;
        color: @textColor;
    }
    div, span {
        .border-box();
    }

That gets compiled as a single CSS file despite being separate files in source. I use Visual Studio + Web Essentials, so this file is also minified for me at compile time.