Collected by
Elizabeth Janson

Home Page

Clashing with Browsers

 

Section A - One style sheet for all browsers

If you've chosen this option, you've selected the easiest of all the methods of ensuring that your page looks o.k. on all browsers. However, you have also selected the method that limits your creative freedom to the greatest extent.

For example, you can't make use of line-height or margin-top declarations.

There are far too many bugs to list here, but here's a quick guide:

  1. Avoid margin-top.
  2. Avoid all units (including %, em, etc.) except pixels.
  3. Avoid specifying line heights.
  4. Do not use the normal keyword on the font shorthand (it is superfluous anyway).
  5. Do not use numerical font weights on the font shorthand.
  6. Set margin-left and margin-right only on BODY.
  7. Avoid all styles on LI, DD and DT.

In addition if you use tables, you will need to separate your BODY selector into two parts: one for inherited properties, and the other for non-inherited properties. For example:

BODY {font-family: sans-serif;
color: red;
background: white;
margin-left: 7%;
margin-right: 5%;
margin-bottom: 2em}

Becomes:

BODY {font-family: sans-serif;
color: red}

BODY {background: white;
margin-left: 7%;
margin-right: 5%;
margin-bottom: 2em}

Next, add every block element except for LI, DD and DT, plus SPAN to the inherited ruleset:

ADDRESS, BLOCKQUOTE, BODY, DIV, DL, H1, H2, H3, H4, H5, H6, OL, P, PRE, SPAN, UL {font-family: sans-serif;
color: red}

The reason that this is necessary is that Netscape 4 and Internet Explorer 3 are very badly buggy and when they encounter a table, the usual result is the termination of BODY's style for the table and all subsequent content.

Note that this is only a very brief guide, but it should help you on your way to bug-free style. If you want to see a sample style sheet converted to a suits-all style sheet, you can do so, but you should take a look at the rest of the master class first.

Section B - Hacks to hide style from browsers

This section is pretty similar to the last one, except it aims to be more adventurous in terms of what it achieves. The essence of this section is the exploitation of the browser bugs in order to hide style from certain, or else to only apply style to certain browsers.

Generally, the browsers that cause 99% of the problems are Internet Explorer 3 and Netscape 4. In view of this fact, it is useful to have methods that will hide styles from these browsers.

The principal method to exclude Internet Explorer 3 and Netscape is:

/* This is a style sheet */
@import url(okbrowsers.css);

Stuff that works in all style sheets goes here; all other styles go in okbrowsers.css.

If these aren't enough, here are some more hacks to hide styles from each of the browsers (note that many of these are invalid CSS):

Internet Explorer 3

  1. Include element_name#id as part of the selector to hide from IE 3 - DIV#body P {line-height: 1.2} will hide the declaration from IE 3 (#body P wouldn't).
  2. Use multiple LINKed style sheets - in IE 3 for Windows, all but the last will be ignored. For example:

    <LINK rel="stylesheet" href="WillNotBeReadByIE3.css" type="text/css">
    <LINK rel="stylesheet" href="awayie3.css" type="text/css">

    Awayie3.css must contain at least one non-whitespace character; for example, if you just put .dummy {color: red} in it, it would hide from IE 3.

  3. Include hyphens inside classes or IDs.
  4. Use LINKed style sheets with embedded ones - in IE 3 for Windows, the embedded one will be ignored. For example:

    <STYLE type="text/css">
    /* Won't be read by IE 3 */
    </STYLE>
    <LINK rel="stylesheet" href="awayie3.css" type="text/css">

  5. Precede a declaration to be hidden by a one line @rule; for example, @cheese "bah"; .hidden {}.
  6. Use embedded style sheets - in IE 3 for Windows, all but the last one will be ignored.
  7. Have the property immediately followed by a comment; for example, color/* comment */ : red.
  8. Where the same property is specified on an element in several different declaration blocks, IE 3 ignores all but the first:

    P {color: red;
    font-size: 14pt}
    P {color: green}

    This would make P red, because the redeclaration is ignored (though P {color: red; color: green} works correctly).

    Thus for each of IE3's buggy properties it is possible to have one declaration for IE 3 and one for everyone else. E.g.:

    BODY {color: black}
    BODY {color: white;
    background: black}

    In normal circumstances this would cause major problems because IE 3 doesn't support background on BODY in LINKed style sheets. In this case however, the fact that the color is white won't clash with IE3's background because it ignores color: white and applies color: black instead.

  9. Include a comment inside a simple_selector; for example, P/* comment */.class
  10. Enclose style in @media all {} (or @media screen). This will only hide the first ruleset from IE 3, and also requires a subsequent .dummy {}; for example, @media all {.hidden {} .nothidden {} } .dummy {}
  11. Link styles via @import - IE 3 doesn't support @import.
  12. Omit the HTML or BODY tag and declare styles using the HTML/BODY selector
  13. Use the backslash to hide - P \{ {color: red; background: green} hides from IE 3, but not from compliant browsers (at present only Mozilla 5 fits the bill).

Internet Explorer 4

  1. Use the string format of @import instead of the url() format; for example, @import "hiddenfromie4.css"; would hide it from IE 4.
  2. Follow the property by a comment; for example, color/* */ : red
  3. Use @import with a medium - e.g., @import url(hiddenfromie4.css) screen;
  4. To apply only to IE 4, P/* comment */ .class {}

Internet Explorer 5

  1. Follow the property by a comment; for example, color/* */ : red

Opera

  1. Apply style via an @import that doesn't precede all rulesets; for example, P {} @import
  2. Add a class or id to BODY and add this to the selector; for example, BODY.class P {hidden}
  3. Use P, {}. Note that this is valid CSS, since simple_selector is partly defined by element_name?
  4. Use a case-insensitive match of a class or id; for example, with <DIV id="body">, #Body P to hide them from Opera
  5. Have style in an @imported style sheet specified for screen (not all) specified in a position other than first in a list; for example, @import "hidden.css" madeup, screen;
  6. Enclose the property value in quotes; for example, color: "red"
  7. Use a ' as a fake identifier character to hide everything that follows it from Opera; for example, P.dumm'y {}
  8. Use the SGML comment open tag on the same line as a selector to hide the declaration from Opera - e.g., <!-- P {color: red} (note that thhere must not be a line break before the selector)
  9. Use the backslash to hide from Opera - P \{ {color: red; background: green} hides from Opera
  10. When specifying in pixels, omit the px to hide the declaration from Opera; for example, margin-top: 12 [note this only applies to box model properties - on font-size and line-height, it hides from Netscape as well].
  11. Omit the # from colors to hide from Opera

Netscape 4

  1. Use !important - Netscape ignores it; for example, P {color: red !important} P {color: blue} would apply blue in Netscape (and IE 3 (although for a different reason - IE 3 ignores the whole declaration (provided the property takes as its value a single identifier), Netscape just the !important bit)) and red in IE 4-5 and Opera
  2. Enclose style in @media all {} (or @media screen)
  3. If specifying font-size in pixels, omit the px to hide from Netscape; for example, font-size: 12
  4. Have a line break between the ! and the important to hide the whole declaration from Netscape
  5. Add a fake @rule to a ruleset to hide the subsequent ruleset from Netscape - .dummy {color: @hello {}; color: red} .hiddenfromnetscape {color: red}
  6. Use the backslash to hide from Netscape - P \{ {color: red; background: green} hides from Netscape
  7. Link styles via @import - Netscape doesn't support @import
  8. Designate the style sheet as for media="all" (e.g., <LINK href="css.css" rel="stylesheet" type="text/css" media="all"> ;<STYLE type="text/css" media="all">) - this will hide it from Netscape
  9. Include a comma in the media declaration, e.g., media="screen, all"
  10. Apply styles using the HTML selector - Netscape doesn't support it
  11. Include element_name#id as part of the selector to hide it - DIV#body P {line-height: 1.2} will hide the declaration from Netscape (#body P wouldn't)

Section C - Separate style sheets for each browser

Having decided on this option, you need a script to serve the right style sheet on your users.

However, you will also need a style sheets for users who aren't, for any reason, detected by the script, or who have disabled scripts. This should be a style sheet that works on all browsers.

Next you need an inline script for IE 3 users (since IE 3.0 and 3.01 don't support src). This script must serve one style sheet to users using 3.0 for Windows and one for users using 3.01+ or 3.0 for the Macintosh.

Here's the script (which is 278 bytes long):

ua=navigator.userAgent;
l='<LINK rel="stylesheet" type="text/css" href="ie3';
if (ua.indexOf('IE 3.0')!=-1){
    if (((ua.indexOf('IE 3.0A')!=-1) || (ua.indexOf('IE 3.0 ')!=-1)) && (ua.indexOf('Mac')==-1)) document.write(l+'0.css">');
    else document.write(l+'.css">');
}

The above script is copyright RichInStyle.com 2000. You may only use it within the SCRIPT element of your page. You may modify it, but must not exhibit the source code publicly.

If you wish to know the purpose that the SCRIPT above is serving, it is to allow you to give IE 3 users different margins on different elements - without it you cannot do this, but are confined to only specifying margins on BODY for IE 3 users.

The decision on this matter is entirely yours. However, if you do specify margins on elements other than BODY, then it is only considerate to offer IE 3 users them as well. Therefore, even if you don't need separate style sheets now, I recommend that you retain them (and thus the SCRIPT above) for the future. Without the SCRIPT above, for example, IE 3 users would be faced with the ugly sight of this page without its outdented headings.

The next thing to do is to add a SCRIPT to detect the other browsers. All the other css-supporting browser support the src attribute, and so therefore since the style sheets are being LINKed, you would be mad not to include the script below in an external file (it is 568 bytes long so presents no significant download time):

/* (c) 2000 RichInStyle.com (www.richinstyle.com); you may only use this script in the SCRIPT element of a page. You must not alter or remove this message */
ua=navigator.userAgent;
l='<LINK rel="stylesheet" type="text/css" href="';
c='.css">';
if (ua.indexOf('IE 4')!=-1)document.write(l+'ie4'+c);
if (ua.indexOf('IE 5')!=-1)document.write(l+'ie5'+c);
if (ua.indexOf("Opera 3")!=-1)document.write(l+'op3'+c);
else if (ua.indexOf("compatible")==-1) {
  if (ua.indexOf("/4")!=-1)document.write(l+'nn4'+c);
  if (ua.indexOf("/5")!=-1)document.write(l+'nn5'+c);
}

This script is copyright RichInStyle.com, and although you may modify it, you must not alter or remove the copyright message, and must not exhibit the source code publicly.

Having done this, you now have a template file that looks like this (i.e., you must include the following in your HTML):

<HTML>
<HEAD>

<!-- Optional: -->
<STYLE type="text/css">
</STYLE>

<LINK rel="stylesheet" href="all.css" type="text/css">
<SCRIPT type="text/javascript">
<!--
ua=navigator.userAgent;
l='<LINK rel="stylesheet" type="text/css" href="ie3';
if (ua.indexOf('IE 3.0')!=-1){
    if (((ua.indexOf('IE 3.0A')!=-1) || (ua.indexOf('IE 3.0 ')!=-1)) && (ua.indexOf('Mac')==-1)) document.write(l+'0.css">');
    else document.write(l+'.css">');
}
// -->
</SCRIPT>
<SCRIPT src="style.js" type="text/javascript"></SCRIPT>
<BODY bgcolor="#xxxxxx" text="#xxxxxx" alink="#xxxxxx" link="#xxxxxxx" vlink="#xxxxxx">

Creating the style sheets

There are two approaches that reveal themselves:

  1. Put the styles that work in all.css and use op3.css, ie5.css, etc., to modify it
  2. Make each style sheet individually complete

It would seem initially that the first of these methods is the more attractive. However, a little experience reveals the fact that this is not so. For example, if you could put only color and font declarations in all.css and had to put margin and padding declarations in the browser-specific style sheets, then the task would be much easier. This is not the case unfortunately - it is not possible to include any one property in all.css: color, margin, padding and font all suffer from bugs that mean that you'd have to include padding except for on x and y, or margin except for on a and b. As a result, you should adopt the second approach.

You need to create 8 style sheets, one for IE 3.0 (ie30.css), one for IE 3.01-3 (ie3.css), one for IE 4 (ie4.css), one for IE 5 (ie5.css), one for Opera (op3.css), one for Netscape 4 (nn4.css), one for Mozilla 5 (will become Netscape 5) (nn5.css) and one for all browsers.

If this sounds like an onerous task, do not fret - in most cases, the Opera, Mozilla 5, IE 4 and IE 5 style sheets will be identical, and the IE 3.0 and 3.01-3 all but identical (apart from margin-left declarations). In addition, you are not actually creating separate style sheets, but are merely fixing an existing one.

It is here where the virtues extolled in RichInStyle.com's guide to writing perfect style sheets come into their own. You should ensure that your own style sheet conforms to these guidelines, or else it is likely that you will suffer serious difficulties.

In addition, you should avoid embarking upon the task of fixing your style sheet for the individual browsers until it is finished. This will save much wasted time. If you later find that changes are necessitated, you should ensure that you update all of your style sheets at once.

In order to undertake this process, you will need to take advantage of RichInStyle.com's browser bug guides. However, I strongly recommend that you do not do this until you have read the rest of the master class, since it is probable that you will make changes to it as a result of reading the rest of the master class.

Conclusion

If all this is getting you down, you could just take the easy way out, and just write for Internet Explorer 4 and 5 and Opera. You do this by linking your style sheet via an @import statement.

This will exclude nasty old Netscape 4 and Internet Explorer 3, and save you the bother of working round all their bugs, thereby allowing you to treat them in the same way as non-css supporting browsers. Thus:

<HEAD>
  <STYLE type="text/css">
  @import url(style.css);
  </STYLE>

Note that you must use the url() form of @import, not the string format (" " or ' ' ).

Email
CSS begins here
Back to side-bars The end - back to the CSS start-page.

This page is part of Elizabeth Janson's web site

http://www.oocities.org/elizatk/index.html

My other sites are the Anglican Parish of Northern Mallee,
Tetbury residents in the Eighteenth Century
my Australian Family History and Barrie, our Family Poet.