www.RickBull.com > tutorials > Cascading Style Sheets > Browser Work-arounds

Cascading Style Sheets - Browser Work-arounds

This tutorial will show you some methods of getting things to work in buggy browsers. Some include exclusion of whole style-sheets, others simply exclude parts of them.

I found some of this information quite some time ago at Johannes Koch's How to hide CSS from buggy browsers page. Also see [the slightly esoteric] Centricle CSS filters site for another great resource and plenty of related links.


The media attribute of the <link> element allows you to specify which output devices your style-sheet should apply to. For example you can make the user agent only use the style sheet if the output device is a (non-paged) computer screen like so:

<link href="style_sheet.css" media="screen" rel="stylesheet" />

You can also specify that your style-sheet can apply to more than one medium by seperating them with commas:

<link href="style_sheet.css" media="screen,projection" rel="stylesheet" />

But Netscape Navigator 4.x browsers have a bug whereby they do not use the style-sheet if the media is set to anything other than screen. This includes using more than one medium as described above.

So if you want to specify a style-sheet that Netscape Navigator 4.x browser do not use you can either specify the media as anything other than screen (e.g. all), or specify more than one media type, so long as the media types are similar - you probably would not want to use the same style-sheet for a screen as you would a tele-type device (tty):

<link href="style_sheet.css" media="screen,projection" rel="stylesheet" />

This would result in most newer browsers (e.g. Mozilla, Microsoft Internet Explorer 5+, Opera, etc.) reading the style-sheet file, and Netscape Navigator 4.x ignoring it totally.


The @import rule.

The @import rule imports the specified CSS file into the current one. For example, if you put this text at the top of your CSS code it would import all the text from the file import_style.css:

@import url("import_style.css");

But once again Netscape Navigator 4.x browsers, and also Internet Explorer 4.x and earlier have a bug with this rule, and do not import any of the specified file. So in your main CSS file (the one with the @import rule in it) you can place code that will work in both Netscape Navigator 4.x & Internet Explorer 4.x and newer, more CSS complient browsers, and in the imported file (import_style.css in this case) you can place code that only better browsers will understand.

Take this code for example, and say that the code that belongs to #menu and #menu a does not work in Netscape Navigator 4.x, but the rest does:

#menu {
  float: left;
  width: 10em;
  height: 100%;
  overflow: auto;
}

#menu a {
  display: block;
}

body {
  background: white url("image/background.png")
    top left repeat-y;
  color: black;
  font-family: Tahoma, Verdana, 
    "Trebuchet MS", sans-serif;
}

/* And so fourth… */

So normally here we would have the choice of either leaving the code as it is, and having the page look horrible and perhaps unreadable in Netscape Navigator 4.x, or scrapping the code that is giving us trouble all together and missing out on the desired layout for the newer, comfirming browsers.

But with the use of the @import rule we can shift this troublesome code to another CSS file, and have the newer browsers import it and use it, while Netscape Navigator 4.x will never know that it even exists! So if we move the troulbesome code into a file named menu.css, we could replace the code in the orignal file with something like this:

@import url("menu.css");

body {
  background: white url("image/background.png") top left repeat-y;
  color: black;
  font-family: Tahoma, Verdana,
    "Trebuchet MS", sans-serif;
}
/* And so fourth… */

And now our page will look exactly as it should in newer browsers, and not quite what we want in Netscape Navigator 4.x & Internet Explorer 4.x, but still totally useable and readable.

Note: It is required that you place all @import rules at the very top of your CSS file, otherwise conforming user agents will ignore them.

For more information on the @import rule please visit http://www.w3.org/TR/REC-CSS2/syndata.html#at-rules.


The @media rule.

The @media rule allows you to put CSS commands in your style-sheets that will only be used by the specified media type. For instance if we wanted a group of rules to be used only by the screen media, we could write something like this:

@media screen {
  /* Rules for screen go here */
}

But a bug in Netscape 4.x and earlier, Internet Explorer 4 and earlier (on Mac this also includes version 5) and Konqueror 3 and earlier make these rules invisble to them. So as above if we wanted to exclude a section of code from these browsers we could do something like this:

/* Buggy browsers will ignore this: */

@media all {
  #menu {
    float: left;
    overflow: auto;
    width: 10em;
    height: 100%;
  }
}

/* All browsers can see this code: */
body {
  background: black url("images/background.png");
  color: white;
}

rgb Colours, and Negative Values

When you specify colours you can use the rgb function to specify the red, green and blue values like so:

body { background-color: rgb(255,0,255); }

…which would result in a fuchsia background. User agents are supposed to clip values that are above 255 or below 0 (the range in which a colour can occur); But Netscape 4.x has a problem with negative values, and will ignore any colours you specify that contains them. So, for exmaple, this would result in most browsers using a fuchsia background, but Netscape not, and using the default colour:

body { background-color: rgb(255,-1,255); }

So conforming browsers would clip this to rgb(255,0,255), but Netscape 4.x simply ignores the rule all together. The only downside to this work-around is that you will recieve a warning when you try to validate your style-sheets.


Advanced selectors

Selectors, as the name implies, allow you to apply style-sheet comands to particalar elements. Usually we just use them via classes. elements or IDs, but they can be more complicated than that. For instance, we could only apply a style to an input element, if it had a type command of text:

input[type="text"] { /*style commands here*/ }

So if an input element has a type attribute value of text all the style-sheet commands would be used, but any other input element would not use them.

Unfortunatly not all selectors are supported by Microsoft's Internet Explorer 6 or earlier (the Windows version at least) . But in someways this a blessing, as Internet Explorer's CSS support can be pretty bad (or just slightly off in some cases). So we can use some of these tricks to apply styles to better browsers, and have them ignored in Internet Explorer.

There are several selectors that do not function properly in Internet Explorer, which are outlined here:

XXX:first-child
The first child-element of the XXX element
XXX > YYY
Matches any YYY element whose parent is XXX. Note, YYY must be a direct child of the parent, not just a descendant of the parent.
XXX:lang(LANG CODE)
Matches XXX when it has its language attrubute set to LANG CODE.
XXX + YYY
Matches YYY when it is preceded immediately by XXX
XXX[YYY]
Maches XXX when it has its YYY attribute set, whatever its value
XXX[YYY=ZZZ]
Matches XXX when its YYY value equals exactly ZZZ
XXX[YYY~=ZZZ]
Matches XXX when at any one of its YYY (space-seperated list of) values is exactly equal to ZZZ
XXX[YYY|=ZZZ]
Matches XXX when its YYY value is equal to any value starting with ZZZ then a hypen and anything else. This is often used with language code, e.g. <p lang="en-US">.

So using any of these selectors will result in better browsers (such as Mozilla, Netscape 6.x+ and Opera) being able to understand them, and so apply the style commands to selected elements, and Internet Explorer not using them.

One thing you can do is set the value of an element using a method that Internet Explorer will understand (as well as the other browsers), then using a selector as described above to overide that value with one that more conforming browsers will understand. One obvious example of this if when we want to use fixed positioning; As Internet Explorer does not cope with fixed positioning, but other browsers do, we can let Internet Explorer use absolute position, and all other browsers use fixed:

/* IE will understand this */
#menu {
  position: absolute;
}

/* IE will not understand this, but as body is a child of html,
 and #menu is a descendant of body, most other browsers will */
html > body #menu {
  position: fixed;
}

/* Allow all browsers to see this */
#menu {
  top: 0px;
  left: 0px;
  width: 10em;
}

If you would like to try this, add a <div> tag to your page with an id of menu, with some content in it, and before or after that tag add a <p> tag with enough content to make the page scroll a fair bit. Now open the page in Internet Explorer, and you should notice that the <div> scrolls when the page is scrolled, but if you open the page in Mozilla or Opera it should stay fixed in position, regardless of whether the page is scrolled or not.

For more information on selectors please visit http://www.w3.org/TR/REC-CSS2/selector.html.


All tutorials and content written by Rick Bull unless otherwise stated
Page's last update: Friday, 26th November 2010; 09:21:10 UTC +0000
Top of the page