Author Home Contents Wiley Home

Cross-Browser Compatible Style Sheets

by
Ian Graham
Exerpted from
The XHTML 1.0 Web Application Sourcebook

On this Page:
Browsers and CSS
Internet Explorer 3
Navigator 4.x
Internet Explorer 4
Internet Explorer 5.x
Opera 3.6
Opera 4 and Mozilla/Navigator 6
Style Sheets for Multiple Browsers

4.3.1 Browsers and CSS

CSS is supported by most recent browsers--in particular Internet Explorer 3 and up and Navigator 4 and up. However, the support in Internet Explorer 3 is quite poor, mainly because the browser was released before the CSS specification (Level 1) was finalized. As a result, many features were implemented in a manner inconsistent with the final specification. CSS support in Navigator 4 is better but still not very good: some language elements are not supported at all, while many others are very buggy and cannot be used reliably.

TIP-- CSS Compatibility Charts
For a very complete list describing CSS support on various browsers, please see Eric Meyer's compatibility charts, at http://www.webreview.com/style/index.shtml (this is an updated URL). Some other useful CSS tutorials and bug/workaround lists are found at: http://www.css.nu, http://www.richinstyle.com/, and http://www.htmlhelp.com/reference/css/.

Eric Meyer, Hypermedia Systems Manager for Case Western Reserve University, has summarized these various bugs, unimplemented features and odd behaviors in a series of CSS compatibility charts, found online at
http://www.webreview.com/style/index.shtml (updated URL!)
These charts explicitly describe the state of the different browser's support for CSS, and make it easier for you to design using CSS, and are absolutely essential for anyone trying to build style sheets that work reliably across different browsers.

However, there is a lot in these charts, and it is often hard to translate this chart into a set of useful guidelines. The following short sections describe the most important features to consider if you need to design style sheets that support specific browsers.

Some other useful guides to CSS usage, problems, and bugs, are found at:
http://www.css.nu
http://www.richinstyle.com/
http://www.htmlhelp.com/reference/css/.

Internet Explorer 3

Although it supports some aspects of CSS, it is probably best to avoid CSS if designing for Internet Explorer 3. This is because it is almost impossible to design a style sheet that works with Internet Explorer 3 and that also works with any other CSS-aware browser. If you must use a style sheet, the best approach is to create a style sheet for Internet Explorer 3 independent of the style sheets used for other browsers. One possible approach for doing this shown at the end of this section.

Navigator 4.x

Navigator 4 supports CSS Level 1, but in a manner best described as "shabbily." In particular, some features are not supported at all, while others are supported in buggy and inconsistent ways. The guidelines in this section will help you avoid the most glaring CSS problems, while at the same time let you write CSS formatting properties that will work properly on most other browsers, such as Internet Explorer 4 and greater, or Opera 3.6 and greater. Mind you, please beware that complex CSS designs will force you to do lots of extra design testing, since CSS can act very differently on different browsers--it is easy for a seemingly innocuous CSS change to cause odd and undesirable rendering on one of the browsers you must support!

The following, in point form, are some useful rules for using CSS with Navigator 4.

Internet Explorer 4

Internet Explorer 4 supports CSS Level 1 fairly well, albeit with a few signifiant problems. It certainly gets the main language rules correct (inheritance, cascading mechanism, and so on.), so that the problems do not lie in incorrect handling of style sheets. The problems are due to incorrectly implemented CSS properties, and with those that are not supported at all. In general, however, it is much easier to get things to work on Internet Explorer 4 than Navigator 4.

In point form, here are the things that you most need to watch out for.

Internet Explorer 5.x

Internet Explorer 5.x supports CSS Level 1 in essentially the same manner as Internet Explorer 4. Indeed, the only differences are that:

Otherwise, the support problems are pretty-well the same as those described above for Internet Explorer 4.

Internet Explorer 5 also supports some features defined in CSS Level 2. We won't go into the details here--This information is summarized in The XHTML 1.0 Language and Design Sourcebook, and is also found at msdn.microsoft.com/workshop/author/css/reference/attributes.asp

Opera 3.6

Opera 3.6 does a pretty good job with most of CSS Level 1, with the following exceptions:

Opera 4 and Mozilla/Navigator 6

Opera 4 essentially supports all of CSS Level 1 correctly, as does the Mozilla/Navigator 6 browser. Mozilla, however, also supports most of CSS Level 2. For details on Navigator 6 support, please see The XHTML 1.0 Language and Design Sourcebook.

Style Sheets for Multiple Browsers

Given these inconsistencies it can be messy (if not impossible) to design a single style sheet that works properly on all the different browsers. One option is to use different style sheet documents for the different browsers you want to support. In this way you can specify CSS formatting customized to the strengths (and weaknesses) of each different browser, without compromising for the average of them.

There are essentially two ways to do this. The first is to use content negotiation to send the browser a browser-specific style sheet. This is analogous to the approach described in Section 4.2.4, except that here you use the browser's identity to determine which style sheet to return. With HTTP, a request for any resource (including a style sheet) will look something like (omitting several other pieces of information):

GET /path/stylesheet.css HTTP/1.0
....
User-Agent: Mozilla/4.61 [en] (Win98; I)

The User-agent string uniquely identifies the browser (here Navigator 4.6). Most Web server can be configured to return different style sheet documents depending on this value. Unfortunately, this breaks caching on some proxy servers, so it doesn't always work. Also you, as an an author, may have not control over server configuration.

The second way is to use JavaScript to test, on the browser, for the browser version and model number, and to then "write" link elements referencing appropriate style sheets directly into the document. Both Navigator and Internet Explorer will then process the script-generated link elements, and will load the referenced style sheet. Of course, this will only work if JavaScript is enabled, but in many cases this may be an entirely acceptable requirement.

An example of this is shown in Figure 4.5. This figure lists part of the content of a document head, showing the markup related to style sheets. The first link element is independent of the browser, and loads "generic" style sheet rules that apply in all cases. This, for example, could set generic font properties using CSS rules that are valid with all browsers.

The script elements set up a special JavaScript object, named is, that identifies the browser type and version--The code that does this is included from the external file browser-detect.js, so that this function can be shared across many different XHTML documents. However, some older browsers (e.g., Navigator 2, Internet Explorer 2) cannot include external scripts, in which case the is object is not created, so that subsequent code will fail. The two small script blocks before and after the browser detect script fix this problem. The first piece,

<script><!-- is = null; // --></script>

sets is=null, ensuring that the variable exists and is assigned a null value. Then, if the next line

<script src="./browser-detect.js"> </script>

successfully loads the script, the variable is is reset to be the object containing the browser data. However, if the script is not loaded, then the value remains null. The next script

<script><!--

if( is == null) { is = new Object(); } //

// --></script>

tests for this case: If the value is still null, then it assignes a new, empty "object" to the variable.

The remaining script uses the is object to test for the browser version. The function browser-detect.js (available at http://developer.netscape.com/docs/examples/javascript/browser_type.html) adds properties to this object according to the type of browser. For example, if the browser is Navigator 5 or greater, then the property nav5up is created and is assigned the value true. In this case, the statement if (is.nav5up) is true, so that the following block of code:

if (is.nav5up) {
  document.write('<'+'link rel="stylesheet" href="style-moz5.css" />');
}

will write, into the document, a link statement referencing a Navigator 5-specific style sheet. Navigator 5 then loads this style sheet into the browser--and caches a copy in the local browser cache.

Figure 4.5. A document that uses a script to insert browser-specific style sheets.

<!-- Load generic default style sheet ic -->

<link rel="stylesheet" href="style-main.css" />

<!-- The 'is' object contains browser version information.
  It is created by the downloaded browser-detect.js script.
  But Older browsers don't load external scripts - so
  just create 'is' now, and let the script replace it if
  the script runs -->>

<script><!-- is = null; // --></script>

<!-- Now load browser-detection script. Original script from:
  developer.netscape.com/docs/examples/javascript/browser_type.html
 -->

<script src="./browser-detect.js"> </script>

<!-- If browser couldn't load script set variable'is' to be a
  new 'empty' object, so the rest of the script will work
-->

<script><!--
  if( is == null) { is = new Object(); }
// --></script>

<!-- Now load appropriate style sheets depending on the browser -->

<script><!--
// Insert browser-specific style sheets. These can overload
// The rules from the 'main' style sheets, to correct for
// idiosyncracies in particular browsers.
if (is.nav5up) {
  document.write('<'+'link rel="stylesheet" href="style-moz5.css" />');
}
else if (is.nav4) {
  document.write('<'+'link rel="stylesheet" href="style-nav4.css" />');
   }
else if (is.ie5up) {
  document.write('<'+'link rel="stylesheet" href="style-ie5.css" />');
}
else if (is.ie4) {
  document.write('<'+'link rel="stylesheet" href="style-ie4.css" />');
}
else if (is.ie3) {
  document.write('<'+'link rel="stylesheet" href="style-ie3.css" />');
}
else if (is.opera) {
  document.write('<'+'link rel="stylesheet" href="style-op.css" />');
}
// -->
</script>
 

There are many browser detection scripts available on the Web--the one used in this example is available from the Netscape Web site, at

http://developer.netscape.com/docs/examples/javascript/browser_type.html

Unfortunately, this mechanism does not work with the Opera 3.6x browser--Opera executes this script code, but does not process the inserted link element, and thus does not load the Opera-specific style sheet instructions. Also, it obviously won't work if the browser doesn't support JavaScript, or if JavaScript support is turned off!


Copyright and Usage: This material is copyright © Ian S. Graham, and is an excerpt from The XHTML 1.0 Web Application Sourcebook", by Ian S. Graham, due for publication in August of 2000 (see: http://www.iangraham.org/books/xhtml2/). Anyone can copy, revise, and reuse this material provided they:
(a) retain the heading credits at the top of the page and this notification at the bottom,
(b) make a note, in the heading, if the text has been revised (and by who), and
(c) acknowledge all contributors (if any, including themselves) to the revised versions, unless explicitly asked not to do so by the contributor.

Valid XHTML 1.0!


© 2000, by Ian S. Graham Last Modified: 15 December 2000