Last updated November 9, 2010. Created on April 8, 2007.
Edited by dealancer, asenseofdesign, chicagomom, NonProfit. Log in to edit this page.

Browser detection using JavaScript is a touchy subject these days.

Setting IE's font size to match the rest of the world's browsers is no easy task. Or is it? Many themers feel a need to adjust the naturally gargantuan tendency of IE's fonts, or use a CSS hack to force IE to comply with a proper box model. Unfortunately for Palm Pilot users, Blackberries, screen readers, and even older versions of Opera, turning to JavaScript browser detection is a failed proposition. There are so many different browsers and screen sizes out there that it becomes impossible to feed each one its own unique style sheet.

The savvy themer will no doubt be asking, "Why not use one style sheet for all browsers, and then use JavaScript to feed IE its own settings?" Good point, but there's a better way than scripting to get this done.

Microsoft has enabled CSS designers to send Internet Explorer its very own set of CSS rules using a modified HTML comment tag. This comment is not a valid tag according to HTML standards, it's just a comment. All browsers should simply ignore it and move on. IE, however, will read this unique tag and follow every instruction inside it. The Conditional Comment is wrapped around a <link> tag that contains IE's very own stylesheet. Here's how it looks:

<!--[if IE]>
    <link href="screenStyle4IE.css" rel="stylesheet" type="text/css" media="screen" />
<![endif]-->

As always with Drupal, there are many ways to achieve this change to the head of every themed html page. Probably the best way is to use the new Conditional Styles Module (http://drupal.org/project/conditional_styles) and modify your theme's .info file to include conditional styles, thus:

; Set the conditional stylesheets that are processed by IE.
conditional-stylesheets[if lt IE 7][all][] = ie6-and-below.css
conditional-stylesheets[if IE 7][all][] = ie7.css

Note: This module only affects the way the theme registry is built. You will need to clear the theme registry before you will see any changes.

You can also use Conditional-CSS Integration module, which allows you to write css code in a way like this:

/* Conditional-CSS example */ 
a.button_active, a.button_unactive { 
  display: inline-block; 
  [if lte Gecko 1.8] display: -moz-inline-stack; 
  [if lte Konq 3.1] float: left; 
  height: 30px; 
  [if IE 5.0] margin-top: -1px; 
   
  text-decoration: none; 
  outline: none; 
  [if IE] text-decoration: expression(hideFocus='true'); 
}

Another way is to place this tag only within the <head> of the page. Once the <link> tag is parsed by IE, any CSS in the screenStyle4IE stylesheet will take over. Remember that CSS is a cascading ruleset, so any overrides to previous rules must necessarily come after the normal CSS include link. Add a Conditional Comment to Garland's page.tpl.php file like this:

<head>
  <title><?php php print $head_title ?></title>
  <?php print $head ?>
  <?php print $styles ?>
  <?php print $scripts ?>
  <style type="text/css" media="print">@import "<?php print base_path() . path_to_theme() ?>/print.css";</style>
   style type="text/css" media="screen">@import "<?php print base_path() . path_to_theme() ?>/screen.css";</style>
   style type="text/css" media="handheld">@import "<?php print base_path() . path_to_theme() ?>/handheld.css";</style>
  <!--[if lt IE 7]>
    <style type="text/css" media="all">@import "<?php print base_path() . path_to_theme() ?>/fix-ie-layout.css";</style>
  <![endif]-->
  <!--[if IE ]>
  <style type="text/css" media="all">@import "<?php print base_path() . path_to_theme() ?>/fix-ie-font-sizes.css";</style>
  <![endif]-->
</head>

This flexibility is astounding! It is now possible to feed a class for layout divs to all browsers, and then override the size, z-index, float, or margins of that div specifically for IE.

Font sizes, you say? But of course! IE's fonts are always one size larger than other browsers. Tame them by specifying style rules in fix-ie-font-sizes.css that are one size smaller that the corresponding rule in your regular stylesheet. For instance, if p{font-size:normal}, then fix-ie-font-sizes would spec p{font-size:small}. This keeps all browsers in somewhat of a uniformity without having to rely on font percentage hacks.

Oh, and if you want to hone in on specific versions of IE, refer to the previous code block for an example. <!--[if lt IE 7]> means "All instances of IE that are less than IE7". For more info on "lt IE6", "lte IE7" and so on, refer to Microsoft's Conditional Comments workshop

You can also create CSS and JS files that are read by everyone except for IE, using a slightly different construction, since in this case the declarations must be outside comments:

<!--[if !IE]>-->
    <style type="text/css" media="all">@import "<?php print base_path() . path_to_theme() ?>/ie-wont-see-this.css";</style>
<!--<![endif]-->

The original forum post on this subject can still be viewed at http://drupal.org/node/16173

Note: Using internal, or inline stylesheets can lead to problems with some browsers (notably Opera and Safari), since they don't always ignore the CSS inside the comments. Using external stylesheets, as described above, seems to resolve this issue.

Looking for support? Visit the Drupal.org forums, or join #drupal-support in IRC.

Comments

gaurav_m’s picture

I changed the above

; Set the conditional stylesheets that are processed by IE.
conditional-stylesheets[if lt IE 7][all][] = ie6-and-below.css
conditional-stylesheets[if IE 7][all][] = ie7.css

to this one to have separate fix for IE 8

; Set the conditional stylesheets that are processed by IE.
conditional-stylesheets[if lt IE 7][all][] = ie6-and-below.css
conditional-stylesheets[if IE 7][all][] = ie7.css
conditional-stylesheets[if IE 8][all][] = ie8.css

the fix for IE 8 not working out

conditional-stylesheets[if IE 8][all][] = ie8.css

---------------------
Silence is Golden
---------------------

Manjunatha’s picture

<link rel="stylesheet" href="<?php print $base_path . $directory; ?>/ie6-fixes.css" type="text/css">
Add above line to page.tpl.php file

dealancer’s picture

You also could use Conditional-CSS Integration module, which allows you to use css in a way like this:

/* Conditional-CSS example */ 
a.button_active, a.button_unactive { 
  display: inline-block; 
  [if lte Gecko 1.8] display: -moz-inline-stack; 
  [if lte Konq 3.1] float: left; 
  height: 30px; 
  [if IE 5.0] margin-top: -1px; 
   
  text-decoration: none; 
  outline: none; 
  [if IE] text-decoration: expression(hideFocus='true'); 
mgifford’s picture

This probably requires adding in a html.tpl.php file, but am still looking into this.

trogels’s picture

The key is no longer conditional-stylesheets but stylesheets-conditional