Improving CSS With .LESSBy Scott Mitchell
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
.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!
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
aelements when the mouse hovers over them. The following style sheet snippet shows how specifying these shared background colors results in repetition.
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:
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:
When .LESS analyzes the operation
@primary_color - #222 it takes the value of the
@primary_color variable and subtracts the hexadecimal value
resulting in the color
#ddc (a slightly darker yellow than
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
#submenurules have two common properties - their
paddingproperties are both set to zero pixels.
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
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
h1elements in the header region, or for all
lielements in a
ulelement 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
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.
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 126.96.36.199). To get the most recent version, head over to the
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
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
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:
This snippet illustrates using variables (
@base_color) and mixins (the
noMarginNoPadding class). The
Styles.less file is referenced via
<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
|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 |
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
Cacheobject. 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:
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
.LESSfiles, with an option to minify the output. For example, to generate a minified file named
Styles.lessas input, run the following from the command-line:
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.
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.