Archive for the ‘Web Design’ Tag

Dynamic CSS for ASP.NET

I’ve recently being doing a bit of web development in ASP.NET and came across (as all web developers must commonly do) the problem of catering for IE’s poor standards compliance regarding rendering/CSS stylesheets. The common solution to the problem is to use CSS hacks, which perform some magic to get pages in IE looking as they ought to appear whilst still displaying correctly in good browsers (Firefox, Safari, etc.). When this fails as it often does, the best (yet slightly horrible) solution is to create separate stylesheets for IE (and possibly for different versions) and then put conditional tags around the references the CSS file(s) in the HTML head section.

<link rel="Stylesheet" type="text/css" href="StyleSheet.css" />
<!--[if lte IE 7]>
<link rel="Stylesheet" type="text/css" href="StyleSheet-IE.css" />
<![endif]-->

This particular example only includes the stylesheet StyleSheet-IE.css if the browser version is less than or equal to IE 7.0 (whereas StyleSheet.css is always linked). Note that the conditional tags can be put around any HTML element so that they are only read when the browser matches the specified conditions. It can sometimes be useful to wrap JavaScript blocks with them.

The latter solution has until now worked well for all my purposes, though a more concise and elegant way of presenting variations of the CSS code to different browsers has always been asking. The problem arose when I was trying to reference stylesheets for ASP.NET themes (CSS files under the App_Themes folder) – because the ASP.NET runtime dynamically adds links to the stylesheets according to the current theme, there’s no way (that I could find) to implement the previous solution using conditional tags.

My own solution was to create a Dynamic CSS processor which runs on the server to process any CSS file according to the browser type/version before returning the content. I have implemented the processor as an HTTP handler that can enabled by a simple reference in the web.config file. The basic idea is similar to conditional tags in HTML, but instead the tags are in the actual CSS code and have the syntax.

[[?[!]{browser} {true result} | {false result}]]

The browser expression is simply the name of the browser for which to check (e.g. “IE”, “Firefox”) and can optionally be preceded by a ‘!’ symbol to invert the condition. The statement is simply evaluated to {true result} if the condition is found to be true, and {false result} otherwise. It can be applied to whole or parts of CSS declarations, but it is important to enclose one or more tags in comment tags (“/*” and “*/”) to avoid syntax errors generated by the IDE. The processor will not recognise the statement unless it is inclosed in comment tags.

Example:

div.main
{
    /* margin-top: [[?IE -4px | 0 ]] */
}

Unfortunately I haven’t yet gotten round to implementing checking of browser version, but it is certainly something on my task list and I will post an update once it gets done.

The code for the HTTP handler is reasonably short and mainly involves RegEx expressions for parsing the CSS files with some lambda expressions for reducing the number of functions/loops. A caching feature is implemented to save the server from reprocessing a CSS file each time it is requested even when the file has remained unchanged.

You can view the full code for the HTTP handler here. Simply copy it to the App_Code folder and add the following references to web.config (the first is for II 6/Visual Studio test server and the second is for IIS 7).

<system.web>
    <httpHandlers>
        <add verb="*" path="*.css" type="StyleSheetHandler"/>
    </httpHandlers>
</system.web>
<system.webServer>
    <handlers>
        <add name="StyleSheetHandler" verb="*" path="*.css" type="StyleSheetHandler"/>
    </handlers>
</system.webServer>

Feedback is welcome and I would be glad to hear if anyone is using this in their web projects.