Tuesday 15 May 2012

Leaner CSS and a couple of tricks.

I have been exploring and using LESS CSS for about a month now, and I must say it's an awesome package. Makes writing stylesheets a lot of fun and adjusting styles suddenly becomes 'less' of a drag.
The ability to add mixins and variables to your CSS workflow makes it a lot more easy to concentrate on the bigger picture, instead of adjusting a load of rules
Easily splitting your sheets into multiple files is another big plus.
Less has a small undocumented feature that might be very useful for developing your LESS CSS libraries: mixins can have nested children. For example:
.some-flowed-text-helper-mixin(){
    font-size: 1.1em;
    line-height: 1.5em;
    
    hr{
        margin: 10px 20px;
    }
    
    img{
        float:left;
    }
}

p, .para{
    .some-flowed-text-helper-mixin();
}
becomes:
p, .para {
  font-size: 1.1em;
  line-height: 1.5em;
}
p hr, .para hr {
  margin: 10px 20px;
}
p img, .para img {
  float: left;
}
This will be very helpful when creating your own LESS CSS libraries, since the client LESS code would be very, very simple:
your library:
.some-typography-elements(@size-multiplier, @text-color, @heading-color, @link-color){
    p{
        font-size: 1em * @size-multiplier;
        color: @text-color;
    }
    h2{
        font-size: 1.3em * @size-multiplier;
        color: @heading-color;
    }
    a{
        color: @link-color;
    }
    hr{
        margin: 20px*@size-multiplier 10px*@size-multiplier;
    }
}
client LESS CSS:
@import "somelibrary/typography.less";

#content{
    // Multiplier of font-size and line-height, text color, heading color and link color
    .tipography-elements(1.0, #222, #444, #22e);
}
#content-2{
    .tipography-elements(0.8, #999, #666, #ccc);
}
The mixin would then add the rules for p, span, hr, h1, h2, etc. Very practical if you had flowed text in several places with different colors. Another use would be picture gallery widgets (they need to style the child images).
This might look like it's nothing (and it probably isn't much anyway), but there is more! You can also use mixins IN THE OPEN. You can declare new classes outside any parent by using mixins!
Take the above example, and let's suppose only one kind of text color and size is needed in the whole page. It wouldn't make sense to nest the text information inside an ID. Too much bloat in the output CSS for no good reason. All you had to do was:
.tipography-elements(0.8, #999, #666, #ccc); 

EDIT: I have decided to call this hidden featurette "global-level mixins".

This feature can be very useful, but it's not something we use every day. So it's good to stay mindful of it. I've used it to style nested menus in JOOMLA without incurring in confusing nesting and indentation:
.level1(){
    /* ... */
    a{/* ... */}
}
.level2(){
    /* ... */
}
.level3(){
    /* ... */
}

ul.menu{
    .level1();
    ul{
        .level2();
        ul{
            .level3();
        }
    }
}
It's a good idea to use this on a CSS reset. It's seldom necessary to reset heading, nav, section, article, span, form, fieldset, table, td, tr, input, textarea, and every other element in the HTML5 spec. Instead, just importing the CSS reset and applying the mixins for the elements needed will spare a lot of CSS. Too many rules and selectors equals too much bloat, making my CSS larger and making my pages render more slowly.
Another use for this would be to avoid importing CSS classes when importing a LESS library. I might just want to use the variables, calculations and mixins, not include the pure CSS classes. Also, including these files several times results in multiple copies of the classes being placed in the CSS. If the library is static (no mixins), the CSS classes can be wrapped in a large mixin which adds the classes, to avoid unnecessary importing.
Have fun playing around!