Sunday, March 23, 2008

Managing Cross Browser issues with JS browser detects & Conditional Comments

posted by Alex Grande
Until all browsers completely comply with w3c specifications we have to find workarounds in order for our websites to be pixel perfect in various browsers. The browsers we need to be most concerned with include Internet Explorer, Safari, and Firefox.

Firefox is a web developers wet dream. It features many plugins that allow a web developer to write CSS, JS, and HTML in real time. Thus you do not need a hack or workaround for Firefox since you are developing your websites in Firefox.

With the release of Safari 3 for both Mac and Windows, Safari is becoming a strong player. When Safari-centric adjustments need to be made, you can use a browser detect, or when you write javascript that detects the user's browser and can set styles only to that browser. You may have heard that browser detects bad and should be avoided, but when you do not have any other options it may be your only hope. Using Core DOM API, or just plain old javascript, browser detect code can be confusing and long. A library, like dojo, prototype, or mootools, can make life get much easier and tasks can be checked off much faster. In jquery, a popular library, it is easy to detect the browser.

In this example, not only do I detect Safari but set a CSS class called "safari" to the tag seen only by Safari's eyes.
// detects the browser in an if statement
if ($.browser.safari) {
   // Writes a class safar on the <body> tag. Or in other words, <body class="safari">
   $("body").addClass("safari");
}
And in this example we write it in Mootools,

if (window.safari) {
   $$("body").addClass("safari");
}


On to Internet Explorer. For styling (CSS) we can use conditional comments placed in your html. Right after the tag insert the following code:
<!--[if lte IE 5]>
<div class="ie">
<![endif]-->
<!--[if IE 6]>
<div class="ie ie6">
<![endif]-->
<!--[if IE 7]>
<div class="ie ie7">
<![endif]-->
Results:

IE5+ gets <div class="ie">

IE6 gets <div class="ie6">

IE7 gets <div class="ie7">

At the bottom of your document, right before the closing tag add these lines of code to close the IE <div>s.
<!--[if IE]>
</div>
<![endif]-->
On to the stylizing in CSS:

To write styles for Safari just start any style rule with .safari. For instance,
.safari div#title {
   margin: 0 0 3px 0;
}
And similar for IE:
.ie div#title {
   position: relative;
}

.ie7 div#title {
   margin: 0 0 3px 0;
}

.ie6 div#title {
   left: 305px;
}
If you have to make browser specific Javascript adjustments only browser detects will suffice. We already covered Safari. For Internet explorer you can write:

Jquery:
if ($.browser.msie) {
   // js goes here for internet explorer
}
Mootools:
if (window.ie) {
   // js goes here for internet explorer
}
Luckily, Safari and internet explorer styling adjustments are often similar. Having already adjusted IE to match Firefox, I usually need to apply similar Safari rules to the same trouble elements.

For example,
.ie div#rightNav,
.safari div#rightNav {
   top: -3px;
}

Labels: , , ,

7 Comments:

Blogger Pau Garcia i Quiles said...

No need to write your own browser detection routines in Javascript, just use jsbrwsniff. It's free, open source and there are thousands of sites and products already using it (for example, Zimbra and Vyatta)

May 22, 2008 at 2:11 AM  
Blogger Rodney said...

You can detect a lot of bots pretending to be real users this way too.... Along with little [script][/script] snippets that try to run javascript 3.0, etc.

May 22, 2008 at 10:27 PM  
Blogger Jonah Dempcy said...

Although Alex explores using JavaScript libraries to detect browsers later in the article, the initial technique demonstrated does not rely on JavaScript.

Hence, it allows the user to detect browsers entirely through HTML/CSS, thus ensuring compatible CSS layouts even for non-JS-enabled browsers.

May 25, 2008 at 2:09 PM  
Blogger Jonah Dempcy said...

Note that if (window.ie) will only work in MooTools 1.11 (and possibly earlier versions). In MooTools 1.2 they changed this to the Browser object and also changed it to the name of the rendering engine rather than the browser name (trident instead of IE, gecko instead of Firefox).


So, instead of checking if (window.ie) you would want to check if (Browser.Engines.trident) ...See docs.mootools.net/Core/Browser for more info.

June 23, 2008 at 12:59 PM  
Blogger Jonah Dempcy said...

Typo in the previous comment:

// Incorrect
if (Browser.Engines.trident)


// Correct
if (Browser.Engine.trident)

June 23, 2008 at 1:00 PM  
Blogger Jim Newman said...

Alex's ie fix for css worked fine for divs but not for class elements. Any solution?

Jim

July 1, 2008 at 11:53 AM  
Anonymous Anonymous said...

I'm adding this to the head section of a wordpress header file:

bracket script type="text/javascript" bracket

if ($.browser.safari) {
$("body").addClass("safari");

}

bracket/script bracket

but am not seeing it render when I check source in Safari.

Am I missing something?

September 10, 2008 at 9:09 AM  

Post a Comment

Subscribe to Post Comments [Atom]

<< Home