Programming CSS Using LESS Preprocessor & Maven Integration


In this article I am going to introduce you to a couple of tools and development practices which are very cool from UI development perspective and I am sure you’ll be tempted to adopt it for your next project.

You can download full working example/source code for this article from my SVN repository at googlecodes http://suryakand.googlecode.com/svn/trunk/boilerplate/

Since last 7 years I am working on web application development using Java/J2EE and various other frameworks. I am not an UI developer and my work is mainly focused on server side development that includes designing application framework and coding them in java (web service, performance tuning, transaction management etc.) Writing code takes less time but, designing stable and maintainable applications is something that needs more time. One of the various must have qualities of a software is reusability. The general rule of software development is “develop reusable components/code”. It’s very easy to achieve reusability when we are writing code/functionality using Java/.NET (or any other language that supports Object Oriented Programming i.e. OOP) but, how to develop reusable and maintainable UI resources mainly CSS and JS? This is the topic that we are going to cover in this article. We’ll mainly focus on CSS in this article but, similar concept and tools are available for JS as well.

CSS, the style sheet language used to format markup on web pages. CSS itself is extremely simple, consisting of rule sets and declaration blocks, what to style, how to style it and it does pretty much everything you want, right? Well, not quite. As far as we all know CSS is static resource and have some limitations. These limitations, like the inability to set variables or to perform operations, this means that we inevitably end up repeating the same pieces of styling in different places. Not a good best practices to follow and difficult to maintain in log run.

There is a solution out there to overcome some of these limitations. The solution is “CSS preprocessor”. In simple terms, CSS preprocessing is a method of extending the feature set of CSS by first writing the style sheets in a new extended language, then compiling the code to classic CSS so that it can be read by web browsers. Several CSS preprocessors are available today, most notably Sass and LESS.

Ok, what’s the deal and how it is useful to me? This might be your first question but, believe me by end of this tutorial you’ll see the real benefit. Let’s start to make our hand dirty. For better understanding, we’ll try to integrate the LESS CSS preprocessor in a real application (developed using Spring MVC and Maven). Here is the focus of this article:

1)      How to write CSS in extended language that will be processed by LESS preprocessor.
2)      Integrate LESS CSS preprocessor in a Maven project.
3)      Use case & how LESS preprocessor is beneficial to us?

Maven is a build tool that is used by a lot of developers/organizations for building and continuous integration of projects. If you want to read more about maven, please visit http://maven.apache.org/. Also, you can read more about LESS CSS preprocessor at http://lesscss.org/.

1.      How to write CSS in extended language that will be processed by LESS preprocessor.

LESS extends CSS with dynamic behavior such as variables, mixins, operations and functions. We’ll see few example in this section that will give us better understanding of these features. It’s like programming CSS not just designing/writing CSS (CSS developers, more fun is coming in your way). First thing, you’ll learn is that the file extension of LESS compatible CSS file is (*.less, e.g. mysite.less). Let’s see how to define variables, functions and how to perform some operations:

a) Defining Variables: Here is an example that shows how to define variables in LESS. A variable name starts with “@” symbol.

/* ==== CSS LESS Variables ===*/
@default-font-family: Helvetica, Arial, sans-serif;
@default-radius: 8px;
@default-color: #5B83AD;



b) Defining Functions: Here is an example that shows an example function definition in LESS. A function definition starts with a “.” symbol. In below example “@top-left”, “@top-right” are function parameters.

/* Generic rounded corner function example */
.rounded-corners(@top-left: @default-radius, @top-right: @default-radius, @bottom-left: @default-radius, @bottom-right: @default-radius) {
 -moz-border-radius: @top-left @top-right @bottom-right @bottom-left;
 -webkit-border-radius: @top-left @top-right @bottom-right @bottom-left;
 border-radius: @top-left @top-right @bottom-right @bottom-left;
}


c) Performing Operations: LESS allows us to perform operations like addition, subtraction, multiplication etc. Here are few examples that show how we can use variables/values to calculate CSS style attributes:

@base-height: 20%;
@body-height: (@base-height * 2);

@default-color: #5B83AD;
@dark-color: default-color + 222;


d) Mixins: In LESS, it is possible to include properties from one CSS ruleset into another CSS ruleset, pretty much similar to extending a Java class from another Java class. So let’s say we have a class “.general-text-color” and we want everything from this class with an additional style attribute to define a CSS class for “h4” tag, this is how we can do it using LESS:

.general-text-color {
    color: @default-color;
}

h4 {
 .general-text-color; /* Mixin example: including other CSS class in current style. See general-text-color style */
 font-size: @heading;
}

Here is an example LESS CSS that I have developed for this example.site.less (Before Preprocessing)

/* ============ CSS LESS Variables and Functions (START) ===========*/
@default-font-family: Helvetica, Arial, sans-serif;
@default-radius: 8px;
@default-color: #5B83AD;
@icon-pencil: 0 -144px;
@heading: 16px;
@base-height: 20%;
@body-height: (@base-height * 2);
@logo-height: 30px;
@logo-width: 30px;

/*Generic rounded corner function example*/
.rounded-corners(@top-left: @default-radius, @top-right: @default-radius, @bottom-left: @default-radius, @bottom-right: @default-radius) {
 -moz-border-radius: @top-left @top-right @bottom-right @bottom-left;
 -webkit-border-radius: @top-left @top-right @bottom-right @bottom-left;
 border-radius: @top-left @top-right @bottom-right @bottom-left;
}

/* rounded corenrs function for well class*/
.well-rounded-corners (@radius: @default-radius) {
 .rounded-corners(@radius, @radius, 5px, 5px)
}
/* ================= END ===================*/


/* ================= Actual CSS Starts Here =============== */
body {
 font-family: @default-font-family;
    background-color: @default-color; /* background-color change example using css less. See variable default-color */
    padding-bottom: 40px;
    padding-top: 60px;
}

.icon-pencil {
 background-position: @icon-pencil; /* background-position change example. See variable icon-pencil */
}

.well {
 .well-rounded-corners; /* rounded corner change example using LESS function call. See function call well-rounded-corners */
}

.general-text-color {
    color: @default-color;
}

h4 {
 .general-text-color; /* Mixin example: including other CSS class in current style. See general-text-color style */
 font-size: @heading;
}

.body-height {
 height: @body-height; /*Operations example: body-height is calculated by multiplying base-heigh with 2 (base-heigh*2) */
}

.logo {
 height: @logo-height;
 width: @logo-width;
}


This is what we get (in site.css) once site.less is preprocessed by LESS.site.css (After Preprocessing)

body {
 font-family: Helvetica, Arial, sans-serif;
 background-color: #5b83ad;
 padding-bottom: 40px;
 padding-top: 60px;
}

.icon-pencil {
 background-position: 0 -144px;
}

.well {
 -moz-border-radius: 8px 8px 5px 5px;
 -webkit-border-radius: 8px 8px 5px 5px;
 border-radius: 8px 8px 5px 5px;
}

.general-text-color {
 color: #5b83ad;
}

h4 {
 color: #5b83ad;
 font-size: 16px;
}

.body-height {
 height: 40%;
}

.logo {
 height: 30px;
 width: 30px;
}


For full set of features and examples please visit http://lesscss.org/#docs.


2. Integrate LESS CSS preprocessor in a Maven project

Ok, now you have basic idea about what is LESS and how to write basic CSS using LESS and what happens before and after CSS preprocessing. In this section we’ll integrate LESS preprocessor with a Maven project so that the CSS that we have written (in extended language) for our project gets preprocessed during build process automatically to generate classic CSS understood by browsers.

We’ll use “lesscss-maven-plugin” maven plugin for preprocessing our CSS. Here is example configuration that you’ll need to add to your pom.xml file to enable LESS CSS preprocessing:


   
   
    org.lesscss
    lesscss-maven-plugin
    1.3.0
    
     ${project.basedir}/src/main/webapp/themes
     ${project.build.directory}/${project.build.finalName}/themes
     true
    
    
     
      
       compile
      
     
    
   
  

Few things to note:
i) “sourceDirectory” tag: this is directory path in our project where.less files (CSS files coded using LESS extended language) resides.
ii) “outputDirectory” tag: This is the destination director where we want our final complied CSS to be placed after build process is finished.
iii) “compress” tag: This tags tells LESS maven plugin whether to compress/minify the preprocessed CSS or not.

For more configuration options visit https://github.com/marceloverdijk/lesscss-maven-plugin (official site of LESS maven plugin).

Here is the maven project structure for the example that I have developed for this article. Download full source code from http://suryakand.googlecode.com/svn/trunk/boilerplate.


Once project is built, we’ll get preprocessed classic CSS in our target folder (as show in above project structure).

3) Use case & how LESS preprocessor is beneficial to us?

In above example I have used LESS with spring’s THEME feature. Basically, I have created single LESS CSS file for two themes “default” and “olive” and have defined variables that’ll be replaced by LESS preprocessor during build process to generate two different theme specific CSS files from a single (site.less) source file. So, one CSS (basically a LESS) file (written using LESS’s extended language) will give us 2 CSS files just by preprocessing/replacing variables during build process.

Here are screen shots of both themes:

Fig. 3: Default Spring Theme


Fig. 3: Olive Spring Theme
 Here are some situations that’ll tempt you to use LESS in your next project:

i) Think of situation where you have to add more themes in future to your project. In traditional way you’ll copy an existing CSS and will manually find all the places in CSS and will replace it with theme specific values but, with LESS you just need to change the variable values and preprocessor will do everything for us.

ii) Another use case is, let’s say a customer asked us to change color and fonts on all existing themes and if we have 20 themes (each CSS of 1000 lines) then manually finding and replacing is time consuming and error prone but, LESS will reduce the time and with no room for error.

There are several other ways in which we can integrate LESS with our projects. To read more about LESS and different ways to use, please visit: http://lesscss.org/#usage

Also, as I mentioned earlier in this article there are various preprocessor available but, mainly LESS and SASS are used. What’s the difference? Sass was designed to both simplify and extend CSS, so things like curly braces were removed from the syntax. LESS was designed to be as close to CSS as possible, so the syntax is identical to your current CSS code. This means you can use it right away with your existing code. Recently, Sass also introduced a CSS-like syntax called SCSS (Sassy CSS) to make migrating easier.

I hope this article will help you to understand basics of LESS and how you can integrate LESS preprocessor with Maven. If you have any question or suggestions please feel free to post them.

Thank you very much for reading. Happy Coding!

Resources


Comments

Anmol Saraf said…
Great Article :)

Best part was the Maven integration really...

Thanks for writing and sharing,
Anmol Saraf
Unknown said…
Thanks for your article.

I found from an article that CQ itself convert from .less files to .css without any configuration.

Now i ceated .less file in my ClientLibrary and specified in my css.txt as myfile.less . It is not converted as expected to .css file though i called my clienLibrary in my page.

Can you please elaborate this.

Thanks,
Sony
Suryakand said…
try compiling your .less files outside AEM and see if they are getting compiled.

Also, if you have used @import in your .less files try to remove them and always included dependent .less files and make sure it is listed before the script that uses it in your css.txt file.

Popular posts from this blog

AEM as a Cloud Service (AEMaaCS) – Architecture Overview

AEM 6.3 - Bundle Whitelisting - Deprecation of administrative authentication

AEM - Query list of components and templates

Custom synchronisation or rollout action for blueprint ?