Browser-specific CSS without Javascript or horrible syntax

So, we all know that browsers have differing levels of CSS support. Working around them can be a pain in the a**, requiring non-standards-based hacks which are very hard to read and debug.

I’d like to write CSS that looks like this:

.ie div.thing
{
…some tweaks for IE…
}

.ff div.thing
{
…some tweaks for Firefox…
}
…etc. Even better:

.ie6 div.thing
{
…curse you old browser…
}

That’s readable, and isn’t polluted with the –moz stuff or <! — If IE –> or whatever. How to do it? Well, on the server, I simply add a class (or classes) to the <body> tag. It ends up looking like this:

…or…

So, every child of <body> inherits the browser-specific class(es). This allows you to use the readable CSS above.

I implemented this in C# as an extension method on HttpBrowserCapabilities. Like so:

namespace ClipperHouse.Extensions
{
public static partial class BrowserCapabilityExtensions
{
public static string CssClass(this HttpBrowserCapabilities b, bool addVersion)
{
string cssClass = String.Empty;

if (b.Browser.ToLower() == “ie”)
cssClass = “ie”;
if (b.Browser.ToLower().Contains(“firefox”))
cssClass = “ff”;

bool isChrome = b.Capabilities[“”].ToString().ToLower().Contains(“chrome”);
bool isSafari = b.Browser.ToLower().Contains(“safari”) && !isChrome;
bool isWebkit = isChrome || isSafari;

if (isWebkit)
{
cssClass = “webkit”;
}

if (addVersion)
cssClass += “ “ + cssClass + b.MajorVersion.ToString();

if (isChrome)
cssClass += “ chrome”;
if (isSafari)
cssClass += “ safari”;

return cssClass;
}

public static string CssClass(this HttpBrowserCapabilities b)
{
return b.CssClass(false);
}
}
}

Then, in my master page:

<body class=””>

Easy-peasy. I added a bit of cleverness that gives you both “webkit” and “chrome” so you can target the rendering engine and/or the browser. Of course, this could go further, recognizing (say) mobile browsers or operating systems. Give me your ideas in the comments.

You should be able to do similar in PHP or whatever. Hope this helps!

PS: One might be tempted to use Javascript/jQuery to achieve the above. But CSS mustn’t depend on JS — we need our pages to degrade gracefully in the absence of JS.

Related: CSS that is scoped only when Javascript is present

PPS, using extension methods in your master page may require adding a line to web.config, let me know if you need help

Published December 7, 2009