Who could ask for more with LESS CSS? (Part 2 of 3–Setup)

Welcome to part two in my series covering the LESS CSS language.  In the first post, I covered the two major CSS precompiled languages - LESS and SASS to a small extent, iterating over some of the features that you could expect to find in them.  In this post, I will go a little further in depth into the setup and execution of using the LESS framework.

Introduction

It really doesn’t take too much to get LESS working in your project.  The basic workflow will be including the necessary translator in your project, defining bundles for the LESS files, add the necessary code to your layouts.cshtml file, and finally add in all your necessary styles to the LESS files!  Lets get started…

New Project

Just like all great experiments in Visual Studio, start up a File > New Project, and create a new MVC 4 Web Application. 

The Base Package

After you have the new project spun up, use the Nuget Package Manager to install the Bundle Transformer: LESS package.

image

This will take care of installing the main translator that we will be using for LESS code (dotless which is another Nuget package), as well as the core framework for the Bundle Transformer library.  The installation will come up with some instructions in a readme file on how to modify your web.config to handle all your *.less requests through the Bundle Transformer, which passes the translating onto dotless.

Where To Put These LESS Files?!

This step isn’t really a requirement, however I find that I don’t like how ASP.Net MVC just has a content directory where they store CSS, content images, css images….  In my project, I went ahead and created a new directory just for styles – LESS files, CSS files, and images that are only referenced in LESS or CSS. 

image

Ignore the MVC directory as this was my testbed for another project I was working on at the same time.  As you can see here, I have:

  1. A top level directory for images which contains only images used in a page
  2. A top level directory for scripts
  3. A top level directory for Styles
    1. A few directories for plugins I am using (Colrizr, JQueryUI, Farbtastic)
    2. Multiple *.less files for different functions (I’ll go over these in a minute)

I find that this layout offers the best separation of content types. 

Bring Out Your Bundles!

The next thing that we need to do is add in the necessary code for the bundling of these LESS files.  Go ahead and open your BundleConfig.cs file, usually located in the /App_Start/ folder of the project.  As you will see in a minute, instead of using the method Microsoft does in the base MVC 4 project, I change things up a bit. 

Define Constants

The first thing I do is define constants for each of the virtual paths that will be used in the bundler:

image

The main reason is that I hate magic strings in my program, so the fact that you first defined a virtual path in the BundleConfig file, and then used that path in the _Layout.cshtml file really irked me.

Add Bundles to the BundleCollection

Next, I am going to define the bundles for my styles in my AddStyleBundles method:

image

That is all it takes to get all of my styles in play with LESS.  The CssTransformer and NullOrderer types come from the Bundle Transformer we grabbed earlier.  If we didn’t use that package, we would have to write our own function (not too hard, but why do it if it’s been done). I use the site.less file as my main hub for LESS - I will cover that more in the next section.

Add Bundles To Layout.cshtml File

With the constants in the BundleConfig file, instead of having to use the same magic string I defined for the bundle virtual path, I am able to do this:

image

Notice here that besides the RenderSection magic strings (something I am working on in another side project), all of the bundles are now based on const strings.  If I need to change the virtual path, I only have to do it in one place.  Nifty!

Get Started!

We are now ready to roll!  As I said in the previous section, I use the site.less file as a central hub for my styles:

image

As seen here, I have a reset.css file which is a simple CSS reset.  Next, I have created a file for managing all my color variables – colors.less:

image

Here, you can see some of the standards I started to use, in this case for color variables.  I define all color variables with the @col prefix.  Currently, I am going for verbose variable names.

The next file imported is my font.less file that defines the typeface information for the site:

image

Simple enough.  A couple of imports for fonts from Google, and then declaring variables for use throughout LESS.  I also set up the heading sizes, margins, etc..  You can also see my current standardization for font declaration strings – @font.

Next, I pull in a mixins.less file that I grabbed from the Twitter Bootstrap library that gives some useful parameterized mixins for use such as border-radius, gradient, box-shadow, etc…

The common.less file is a file that just contains items that I will be defining that can be used across all my LESS files.  Kind of like my own mixins or font-helpers:

image

Finally I have my layout.less file that contains all of my definitions for general site layout – width, main/sidebar widths, footer layout, etc:

image

That’s it!  For the rest of my one off definitions/corrections, I am currently putting them into the site.less file beneath my original imports

Note

Probably my favorite side effect of using the LESS handler/translator while bundling is that it also does a CSS checkup when rendering…  See, when your web.config is set to debug, bundling will output the url to the direct less file, not the bundle, and the http handler intercepts the call, compiles the less, and returns the result.  If there is an error in your LESS code, the CSS file can be returned empty, or may have the error output as a comment on the first couple lines.

If you have the web.config set to not debug, then if there is an error in your code, you will end up with the usual ASP.Net exception page (unless you catch the exception of course), with information regarding the failure of the conversion, such as brace mismatch, undefined variable, etc…  I find it nifty.

Conclusion

This is really just the beginning.  LESS is very powerful and exciting!  My next post will show an actual working example of why LESS is so powerful with its functions and variables…  At least I hope it will! 

As for now, if you have any questions, comments, or suggestions on my current practice, I would love to hear them!  Feel free to drop a comment or shoot me an email using the contact page.  In the mean time, I plan on posting the final post in this series tomorrow or the day after, with my side project, as well as a whole base ASP.Net MVC4 templated project with LESS added in it so that you can check out the layout I have in this post. 

Until next time…

Print | posted on Friday, November 30, 2012 1:13 AM

Feedback

# re: Who could ask for more with LESS CSS? (Part 2 of 3–Setup)

left by Richard L at 12/1/2012 1:39 PM Gravatar
In your main less file, the reset you're importing is a CSS file, not a less. You should avoid this, since it won't actually get combined into your bundled CSS - it'll remain an @import statement and need a second request from the client to load it. Rename it to a .less file and it'll be merged in and you won't need to make a second request to load it.

# re: Who could ask for more with LESS CSS? (Part 2 of 3–Setup)

left by ToString(theory); at 12/1/2012 8:28 PM Gravatar
Hmm... You are right, I didn't even realize/think about the fact that it wasn't being included in the bundle. The only problem though is that if I DO change it to *.less, the font.less file won't import the Google webfont, because now there will be content before it in the output css file, so the imports won't be executed...

I will have to think about what to do with this one. In the mean time, I will go ahead and post up my next blog in a few minutes with the code the way it is here, and then I will update it in the future once I have figured out what to do with the reset.css...

Thanks for the tip!

# re: Who could ask for more with LESS CSS? (Part 2 of 3–Setup)

left by Andrey Taritsyn at 12/6/2012 8:44 AM Gravatar
Tostringtheory, I do not recommend using the Bundle Transformer with built-in minifiers: CssMinify and JsMinify, because this may lead to unpredictable results.

Recommend to remove the following line of code:

corecss.Transforms.Add(new CssMinify());

And then install any of the Bundle Transformer modules, which supports minification of CSS-code: BundleTransformer.MicrosoftAjax, BundleTransformer.Yui or BundleTransformer.Csso (gives the highest compression).

# re: Who could ask for more with LESS CSS? (Part 2 of 3–Setup)

left by ToString(theory); at 12/8/2012 10:11 AM Gravatar
Hi Taritsyn!

So, my question to you would be can you give me examples of where the built in MVC 4 minifiers provide unpredictable results?

Seeing as how they are the default minifiers used by ASP.Net MVC4, I am sure that they have gone through a large amount of testing, and I myself through my many uses of them have not had any problems..

If you can provide me with examples of actual differences of how the css minifier of Bundle Transformer is more reliable or performant than the built in minifiers, I would love to post on the topic to clear things up then.

If the response is to large, I suggest emailing me using the contact form here.

Sorry for the delay in a reply, however work this week went from meh to THE WORLD IS ENDING B/C OUR SITE IS DOWN!!! Just in time I guess..

# re: Who could ask for more with LESS CSS? (Part 2 of 3–Setup)

left by Andrey Taritsyn at 12/9/2012 7:02 AM Gravatar
Nobody says that CssMinify and JsMinify work badly.

Just when you plug instances of CssTransformer and JsTransformer classes, then you plug in a set of transformations (translation code from the intermediate languages and code minification). A set of transformations depends on what the modules of Bundle Transformer you have installed.

For example, if you have installed some minifier-modules of the Bundle Transformer and left plugged CssMinify and JsMinify, it will lead to double minification of code. In addition, minifier-modules of the Bundle Transformer do not produce the re-minification of code of pre-minified assets (for example, files with the extension *.min.js and *.min.css), that speeds up the process of optimization.

Also note, that CssTransformer and JsTransformer created on the basis of the Microsoft Ajax Minifier (http://ajaxmin.codeplex.com). Therefore, as a their replacement you can use minifier-module the BundleTransformer.MicrosoftAjax (http://nuget.org/packages/BundleTransformer.MicrosoftAjax), which supports a newer version of the Microsoft Ajax Minifier algorithm and allows you to make a more fine-tuning of this algorithm.
Post A Comment
Title:
Name:
Email:
Comment:
Verification: