When you think ASP, think...
Recent Articles
All Articles
ASP.NET Articles
ASPFAQs.com
Message Board
Related Web Technologies
User Tips!
Coding Tips
Search

Sections:
Book Reviews
Sample Chapters
Commonly Asked Message Board Questions
JavaScript Tutorials
MSDN Communities Hub
Official Docs
Security
Stump the SQL Guru!
Web Hosts
XML
Information:
Advertise
Feedback
Author an Article

ASP ASP.NET ASP FAQs Message Board Feedback
 
Print this Page!
Published: Wednesday, March 3, 2010

Improving CSS With .LESS

By Scott Mitchell


Introduction


Cascading Style Sheets, or CSS, is a syntax used to describe the look and feel of the elements in a web page. CSS allows a web developer to separate the document content - the HTML, text, and images - from the presentation of that content. Such separation makes the markup in a page easier to read, understand, and update; it can result in reduced bandwidth as the style information can be specified in a separate file and cached by the browser; and makes site-wide changes easier to apply. For a great example of the flexibility and power of CSS, check out CSS Zen Garden. This website has a single page with fixed markup, but allows web developers from around the world to submit CSS rules to define alternate presentation information.

Unfortunately, certain aspects of CSS's syntax leave a bit to be desired. Many style sheets include repeated styling information because CSS does not allow the use of variables. Such repetition makes the resulting style sheet lengthier and harder to read; it results in more rules that need to be changed when the website is redesigned to use a new primary color. Specifying inherited CSS rules, such as indicating that a elements (i.e., hyperlinks) in h1 elements should not be underlined, requires creating a single selector name, like h1 a. Ideally, CSS would allow for nested rules, enabling you to define the a rules directly within the h1 rules.

.LESS is a free, open-source port of Ruby's LESS library. LESS (and .LESS, by extension) is a parser that allows web developers to create style sheets using new and improved language features, including variables, operations, mixins, and nested rules. Behind the scenes, .LESS converts the enhanced CSS rules into standard CSS rules. This conversion can happen automatically and on-demand through the use of an HTTP Handler, or done manually as part of the build process. Moreover, .LESS can be configured to automatically minify the resulting CSS, saving bandwidth and making the end user's experience a snappier one.

This article shows how to get started using .LESS in your ASP.NET websites. Read on to learn more!

- continued -

Solving CSS's Shortcomings: Variables


One problem with CSS is that style sheets often contain a number of duplicated style rules. For instance, many websites use the same color information in a variety of style rules. The background color of the page's header and footer regions might be the same along with the background color used for a elements when the mouse hovers over them. The following style sheet snippet shows how specifying these shared background colors results in repetition.

#header {
   background-color: #ffe;
}

#footer {
   background-color: #ffe;
}

a:hover {
   background-color: #ffe;
}

When redesigning the site you may decide to change this primary color. Doing so requires that you find each reference to #ffe (or whatever the color may be) and update it accordingly.

.LESS helps reduce such repetition by introducing variables. Like in C# or VB code, variables allow you to associate a name with a value and then reference that value by name. If you want to change the value - from #ffe to some other color, for example - you only need to update the variable declaration. Here's how the above CSS snippet could be rewritten using .LESS:

@primary_color: #ffe;

#header {
   background-color: @primary_color;
}

#footer {
   background-color: @primary_color;
}

a:hover {
   background-color: @primary_color;
}

Solving CSS's Shortcomings: Operations On Variables


.LESS also allows for operations to be performed on variables. If you want the header region to have a bottom border colored a bit darker than the primary color background you can use a rule like so:

@primary_color: #ffe;

#header {
   background-color: @primary_color;
   border-bottom-color: @primary_color - #222;
}

...

When .LESS analyzes the operation @primary_color - #222 it takes the value of the @primary_color variable and subtracts the hexadecimal value #222, resulting in the color #ddc (a slightly darker yellow than #ffe).

Solving CSS's Shortcomings: Mixins


It's not uncommon for multiple CSS classes to include a common subset of rules. .LESS supports mixins, which allow you to define the common subset of rules in one class and then include those rules in other classes, much like how variables work but for all of the rules in a class. Consider the following CSS snippet. Note how both the body and #submenu rules have two common properties - their margin and padding properties are both set to zero pixels.

body {
   font-family: Verdana;
   padding: 0;
   margin: 0;

}

#submenu {
   background-color: #ffe;
   padding: 0;
   margin: 0;

}

With mixins you can move these repeated properties out into a separate class (which I've named noMarginNoPadding) and then reference the new class directly within the body and #submenu rules.

.noMarginNoPadding {
   padding: 0;
   margin: 0;
}


body {
   font-family: Verdana;
   .noMarginNoPadding
}

#submenu {
   background-color: #ffe;
   .noMarginNoPadding
}

Solving CSS's Shortcomings: Nested Rules


Oftentimes, style sheets define rules for elements based on their nesting. For example, a web designer might want to specify rules for all h1 elements in the header region, or for all li elements in a ul element with a particular class name. To accomplish this CSS requires that you use long selector names, which are simply the list of element or class names appended one after another and separated by a space.

.LESS allows a more intuitive way for specifying nested rules. The following CSS snippet shows a common web designer task - defining the CSS rules that format the list items in an unordered list horizontally, a technique commonly used to render menus. Such styling requires defining rules for the ul element, for the li elements inside the ul, and for the a elements (the hyperlinks) inside the li elements. .LESS's use of nested rules makes this definition easier to read and understand and keeps it grouped all in one place.

ul
{
   list-style-type: none;
   height: 30px;
   
   li
   {
      float: left;
      padding-right: 15px;
      
      a
      {
         padding: 5px;
         display: block;
         color: black;
         text-decoration: none;
      }
      
      a:hover
      {
         background-color: @menu_color - #222;
      }
   }
}

Using .LESS's HTTP Handler To Parse CSS On The Fly


The various features offered by .LESS - variables, operators, mixins, and nested rules - are not recognized as accepted CSS syntax. If you were to create a style sheet using variables, for instance, and sent that down to the browser, the variable would not be understood and processed. What .LESS does is takes these .LESS-supported features and generates valid, legal CSS syntax. This conversion from .LESS-supported syntax to legal CSS syntax can be done on the fly when the CSS style sheet is requested by the browser or performed manually using .LESS's compiler program. Let's first look at having .LESS generate the CSS on the fly.

To add .LESS to your ASP.NET website you'll need to add the dotless.Core.dll assembly to your website's /Bin folder. The download available at the end of this article includes the most recent version of .LESS at the time of this writing (version 1.0.0.5). To get the most recent version, head over to the .LESS website.

Next, open Web.config and register the .LESS HTTP Handler. At minimum, add the following to the <httpHandlers> section in <system.web>. (If your site is running on IIS 7 in the integrated pipeline then you'll also want to add an entry to the <system.webServer>\<handlers> section.)

<httpHandlers>
   ...

   <add type="dotless.Core.LessCssHttpHandler, dotless.Core" validate="false" path="*.LESS" verb="*" /> </httpHandlers>

The above markup instructs ASP.NET to dispatch all requests for files with the extension .LESS to the LessCssHttpHandler HTTP Handler. This HTTP Handler parses the CSS rules in the specified file and generates valid CSS rules, which are returned to the requester.

That's all there is to it! Rename your style sheets so that they end with the extension .LESS. You can now use .LESS's enhanced syntax and semantics within these style sheets.

The download available at the end of this article includes a sample ASP.NET website that uses .LESS's HTTP Handler to generate valid CSS on the fly. To see the output, consider the following snippet from the Styles.less file included in the demo:

@base_color: #f63;

.noMarginNoPadding {
   margin: 0;
   padding: 0;
}

body {
   background-color: @base_color;
   .noMarginNoPadding;
}

This snippet illustrates using variables (@base_color) and mixins (the noMarginNoPadding class). The Styles.less file is referenced via a <link> element in <head> element of the master page (<link rel="Stylesheet" href="Styles.less" />), just like you would do with a typical .css file. When the browser requests this file, the .LESS HTTP Handler runs and converts the above CSS snippet into the following, which is what is returned to the browser. Notice how the variable @base_color has been replaced with its value, and how the rules in the noMarginNoPadding class have been replicated in the body rule.

.noMarginNoPadding {
   margin: 0;
   padding: 0;
}
body {
   background-color: #f63;
   margin: 0;
   padding: 0;
}

Configuration In IIS 6.0 or When NOT Using IIS's Integrated Pipeline
If you are using IIS 6 or earlier or are not using IIS's integrated pipeline, you'll need to configure your web server's settings so that requests for .LESS files are routed to the ASP.NET engine (so that they can be processed by the .LESS HTTP Handler). See How ASP.NET Web Pages are Processed on the Web Server for more information. For more information on IIS's integrated pipeline functionality, in which case you do not have to manually configure that .LESS extension files be routed to ASP.NET, see Enhance Your Apps with the Integrated ASP.NET Pipeline.

Caching and Minification


You can configure the .LESS HTTP Handler to apply caching and minification logic to the rendered output by adding a bit more markup to Web.config. (See the .LESS homepage or the demo available for download at the end of this article for details on the needed markup.) The caching option caches the CSS generated by the .LESS HTTP Handler on the server using ASP.NET's Cache object. Minifying the resulting CSS strips out white space and other unnecessary markup to minimize the CSS size. For example, with minification enabled the previous CSS snippet we examined would be crunched into the following:

.noMarginNoPadding{margin:0;padding:0;}body{background-color:#f63;margin:0;padding:0;}

Keep in mind that the caching here refers to caching the valid CSS output on the server. Regardless of whether you have server-side caching turned on, the .LESS HTTP Handler includes HTTP Headers that instruct the browser to cache the resulting CSS content for five minutes.

Manually Generating The CSS Files Using The .LESS Compiler


Along with an HTTP Handler, the .LESS download also includes an executable version of the .LESS engine named dotless.Compiler.exe. This file can be used from the command-line to generate valid CSS files from .LESS files, with an option to minify the output. For example, to generate a minified file named Styles.css using the .LESS file Styles.less as input, run the following from the command-line:

dotless.Compiler.exe -m Styles.less Styles.css

The benefit of using the .LESS compiler to generate static CSS files is that you can let IIS handle the caching of the file rather than relying on .LESS's server-side and client-side implementations. Moreover, you do not have to tinker with Web.config or IIS, as you're dealing with normal CSS files. The downside, of course, is that you must manually run the .LESS compiler to generate the CSS files. However, if you have an automated build and/or deployment process then this should be as simple as adding a couple of lines to your build or deploy scripts.

Conclusion


CSS is the ideal way for specifying presentation information in a web page. While CSS has a lot of expressiveness and power in its syntax, it does have some shortcomings that tend to result in repeated rules in any sizable style sheet. .LESS helps reduce these repetitions by introducing four language enhancements: variables, operations, mixins, and nested rules. These .LESS-specific features can be converted into valid CSS rules on the fly using an HTTP Handler or manually by using the .LESS compiler. Additionally, .LESS can be configured to automatically minify the resulting CSS output.

Happy Programming!

  • By Scott Mitchell


    Attachments:


  • Download the code used in this article

    Further Readings:


  • .LESS Homepage
  • .LESS Discussion Forum
  • Enhance Your Apps with the Integrated ASP.NET Pipeline


  • ASP.NET [1.x] [2.0] | ASPMessageboard.com | ASPFAQs.com | Advertise | Feedback | Author an Article