Use clean browser targeting

This article originally appeared in issue 204 (August 2010) of .net magazine - the world's best-selling magazine for web designers and developers.

Like it or not, browsers do things different ways. We’ll show you how to implement clean, simple browser targeting so you can quickly handle those cross-browser quirks.

There’s more browser choice today than ever before. IE may still be the 800lb gorilla in the room, but Firefox and more recent browsers like Safari and Opera are in wide use and offer a great browsing experience.

What we’ll show you today is how you can set up a framework for quickly tackling those instances where these browsers don’t play nice. We’ve all seen it: Firefox and Chrome handle padding on inputs differently, IE needs explicitly declared widths for floated elements, and so on. Good code will get you 99 per cent of the way – let’s get you set up to handle the other one per cent.

Our first step is to ensure you’ve got the right environment set up.
We’ll need a web server running PHP, either locally or somewhere you can
FTP to. If you’re on a Mac, the built-in web server in System Preferences > Sharing > Web Sharing will work just fine.

Let’s set up a page where we’ll be able to implement and test our solution. We’re going to create a very simple page with some elements we’ll be styling based on which browser you view it in.

<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Browser Targeting Example</title> <meta http-equiv="Content-Language" content="en-us" /> <link href="styles.css" media="all" rel="stylesheet" type="text/css" /> </head> <body> <h1>Clean Browser Targeting is Awesome</h1> <h2>The box below here will be styled based on the browser you load the page in.</h2> <div class="content-box"> <p>This box is different for each of the major browsers. It loads up the icon of the browser and styles the box itself differently. Pretty neat, huh?</p> <a href="">.Net Magazine: Home</a> </div> </body> </html> body { font-family: Helvetica, Arial, Verdana, sans-serif; padding: 30px; } h1 { margin: 0; } h2 { margin: 0 0 24px 0; font-size: 18px; font-weight: normal; color: #777; } div.content-box { width: 580px; padding: 20px; border: solid 1px #ccc; } div.content-box p { margin: 0 0 12px 0; }

Now it’s time for some code. What we need to do first is simply discern which browser the page is being loaded in.

Provide an enhanced experience to newer browsers with newer CSS3 rules while providing a fallback for older browsers

The User Agent String, which identifies every browser, is great (and we’ll use it). But it doesn’t come to us in a terribly usable format.

We’ll use PHP to parse the User Agent String and give us something a little more manageable.

<? // Figure out which browser the user is using $user_agent = $_SERVER[‘HTTP_USER_AGENT’]; if (preg_match('/Firefox.2/i', $user_agent)){ $browser = "ff ff2"; } else if (preg_match('/Firefox.3/i', $user_agent)) { $browser = "ff ff3"; } else if (preg_match('/Firefox.3.0/i', $user_agent)) { $browser = "ff ff30"; } else if (preg_match('/MSIE.8/i', $user_agent)) { $browser = "ie ie8"; } else if (preg_match('/MSIE.7/i', $user_agent)) { $browser = "ie ie7"; } else if (preg_match('/MSIE.6/i', $user_agent)) { $browser = "ie ie6"; } else if (preg_match('/Chrome/i', $user_agent)) { $browser = "chrome"; } else if (preg_match('/Safari/i', $user_agent)) { $browser = "safari"; } else { $browser = "in_unknown"; } ?>

What we’re doing is grabbing the User Agent String and matching it against some short, key descriptors they contain to give us a very simple variable
called $browser.

You may notice that in some cases $browser has a couple of values, such as ff and ff2 – you’ll see why in just a moment.

The first step is to figure out which browser your visitor is using, by making use of the User Agent String

Now that we have a useful, short $browser variable, let’s put it to good use and enable some really clean browser targeting. Change the <body> element in our sample code to:

<body class="<?=$browser?>">

This will give the body of our page a class that denotes which browser we’re using. For example, loading the page in a recent version of Firefox will give the body two classes:

• ff, which is our generic Firefox class, and

• ff3, which tells us we’re in Firefox 3, rather than 2 or 3.0 specifically.

For our purposes here, we’ll just target the generic browsers rather than specific versions. Let’s give our div.content-box some browser-specific styles so that we can test out our solution.

/* @group Internet Explorer */ div.content-box { background: url(ie.gif) no-repeat 20px 20px; padding-left: 60px; } /* @end */ /* @group Firefox */ body.ff div.content-box { background: url(firefox.png) no-repeat 20px 20px; font-family: Georgia, Times, serif; padding-left: 60px; width: 520px; } body.ff div.content-box a { color: #0489b7; } /* @end */ /* @group Chrome */ div.content-box { background: url(chrome.png) no-repeat 20px 20px; border: solid 2px #baccff; color: #555; padding-left: 60px; width: 520px; } div.content-box a { color: #333; text-decoration: none; font-size: 13px; font-weight: bold; text-shadow: 0px 1px 1px #fff; display: inline-block; line-height: 42px; padding: 0 12px; background: -webkit-gradient(linear, left top, left bottom, from(#f4f4f4), to(#ddd)); -webkit-border-radius: 6px; } /* @end */ /* @group Safari */ body.safari div.content-box { background: -webkit-gradient(linear, left top, left bottom, from(#f4f4f4), to(#ddd)); border: solid 1px #ddd; -webkit-border-radius: 3px; -webkit-box-shadow: 0px 3px 6px rgba(0,0,0,0.25); color: #555; } body.safari div.content-box a { background: rgba(0,0,0,0.5); display: inline-block; padding: 8px 16px; color: #fff; text-shadow: 0px 1px 1px rgba(0,0,0,0.5); -webkit-border-radius: 3px; border-top: solid 1px #333; } /* @end */

You’ll notice that in each of the four major browsers, the box and the anchor within it inherit styles based on the browser class we applied to the body – we’ve also thrown in some CSS3 niceties that, if you haven’t checked out, you definitely should.

Our unstyled page, ready to be styled based on which browser the user views it in

That’s all there is to it! With this simple technique you can gracefully apply or override styles for a specific browser, letting you take care of that last one per cent of browser QA. And it should be one per cent – this technique is no substitute for good, cross-browser code.

IE8 tag

A final note: we’ve included code to target IE8 as well, but Microsoft actually did a smart thing with IE8 and built a degree of rendering control right into the browser. Check out this meta tag:

<meta http-equiv="X-UA-Compatible" content="IE=X" />

By substituting 7, 8, or edge for X you can tell IE8 (and in the future, IE9) to render using the IE7 engine, IE8 engine or whatever engine is most recent. In instances where you need to support IE7 and IE8, you can cut down on QA time by having IE8 render as IE7 – you lose almost nothing and you don’t have to QA for two engines.

After we apply our browser targeting code, each browser applies specific styles to the page