:web design/

CSS: coping with old browsers

In these web design articles I’ve mentioned CSS from time to time and devoted a couple of articles specifically to the topic — a basic introduction to CSS and a look at using CSS to describe the layout of web pages. I have tried to emphasise the importance of separating structure and presentation of a web page; in the first of those articles I noted that ideally CSS should be used to describe every aspect of a page’s appearance. However:

There are two enormous problems with this: the first is that only version 4 and higher browsers support CSS; the second is that CSS support is variable and idiosyncratic even in those browser versions which support it. Netscape 4.x browsers are particularly problematic.

That was written almost two years ago, and things have moved on. Most graphical browsers in use now can handle CSS fairly well, although the still surviving (if dwindling) number of people using Netscape 4 remains a problem.

There is a temptation among some web designers to request — or even try to insist — that users of browsers deemed to be “obsolete” (a very good description of Netscape 4) go away and come back with whichever browser they deem modern enough to visit their wondrous web site. This is not a good approach: it seriously pisses off visitors to your site, which even the lamest brain should recognise as being a bad idea. There may be very good reasons why they are not using the latest browsers — Netscape 6+ uses a lot of system resources; Internet Explorer is not available for every platform; the user may not be technically confident enough to install new software. Perhaps they just like Netscape 4 (there’s no accounting for taste). As a web designer, what you have to do is put up with the fact that not everyone uses your favourite browser and bear that in mind when writing your pages.

In fact, when designing a site which makes extensive use of CSS, there are four groups of browsers which you need to bear in mind:

  1. Browsers with no CSS support at all: these don’t cause any problems as far as the CSS is concerned, but you have to structure your document logically, i.e. make proper use of HTML, so that it is fully usable in browsers which don’t support CSS.
  2. Browsers with moderate to good support of CSS1 and support for some parts of CSS2 — this includes most current versions of Internet Explorer for Windows.
  3. Browsers with full CSS1 support and partial CSS2 support — Mozilla, Opera, Internet Explorer 5 for the Macintosh, and Netscape 6/7.
  4. Netscape 4.

CSS2?

CSS2 brought in a lot of features CSS1 did not have. These include support for media types, CSS-positioning (absolute, relative and fixed), control of overflow, clipping and visibility of content, generated content, and new pseudoclasses (such as :hover, :first-child). Full details of the differences in CSS2 from CSS1 are detailed at the W3C site.

As far as I know, no browser supports the full CSS2 standard at the moment, and some support very little of it. There is, though, quite a difference between browsers with fair CSS2 support, the third group listed above, and browsers in the second group which, for example, may well support some positioning of elements with CSS but not recognise position: fixed; or the right or bottom properties; they may also not be able to apply CSS positioning to any element other than a <div>.

The designer looking to create sites using proper separation of structure (HTML) and presentation (CSS) naturally wants to use many of the features which CSS2 provides. The problem arises when a design incorporates style information like this:

#menu {
     position: fixed;
     top: 3%;
     right: 1%;
     width: 18%;
     font-size: .86em;
     border: 1px solid #000066;
     background-color: ##cccccc;
}

This will work perfectly in, say, Mozilla. It won’t work in most versions of Internet Explorer — and that includes IE6 — because the fixed value for position is not recognised, nor is the right property. In Internet Explorer, this menu bar (which should be positioned to the right of the page and remain in place as the rest of the page scrolls) will probably lie to the left of the page, over or under other page content. In Netscape 4 the same applies, plus the border styling will not be recognised and the rendering of the background colour may not be as expected; there may also be problems arising from the use of ems to set font-size.

What we need is some way to deliver the full CSS styling to good browsers which can handle it, decent fallback CSS to poor browsers which can’t, and a further, more basic, fallback for Netscape 4.

How not to do it

The first thought of many of you probably involves some form of JavaScript browser sniffing. I know I have myself explained how to do this; a couple of years ago (a long time for the Internet) it was really the only option, but it was never a very satisfactory one. Now it is also an unnecessary one, and should be considered a bad technique to use. The reasons why it is a bad technique are quite simple.

  1. Many browsers can be set to either identify themselves as another browser (MSIE5, MSIE6, Netscape 4) or not to identify themselves at all. Assuming that a browser which says it is Internet Explorer 5 is Internet Explorer 5 may be disastrous for the web page.
  2. The technique depends upon JavaScript and will therefore fail when JavaScript is not supported or disabled.
  3. A script cannot work even in all JavaScript-aware browsers because there are many, many browsers out there. Just considering the two big names, you may need to differentiate between MSIE3 and lower, MSIE4, MSIE5/6, Netscape 3 and lower, Netscape 4, and Netscape 6 and above. This does not take into account any of the other browsers which are in use (and ignores the fact that many of those other browsers will masquerade as a variety of MSIE or Netscape). It is simply not feasible to write a script which will accommodate every browser in existence.

All of this assumes, of course, that the browser sniffing is done sensibly (if that isn’t an oxymoron) in the first place. Many people who write scripts to detect the browser in use don’t actually check how it identifies itself but look instead for particular elements of the DOM it supports, casually assuming that if a browser recognises document.all it must be Internet Explorer. That doesn’t follow, and nor does assuming it will behave like Internet Explorer.

That isn’t the only form of stupidity which crops up when authors try to check what browser is in use. Few things broadcast that a web site has been designed by a clueless prat than the message “You need a more modern browser to view this site” when you are using Mozilla 1.1 or Internet Explorer 6; even worse is “You need Internet Explorer or Netscape Navigator 4+ to view this site” when you are using Internet Explorer 6 or Netscape 7!

Fortunately, when it comes to providing different stylesheets for different browsers JavaScript is completely unnecessary. The secret lies in using multiple external style sheets.

Linking & importing

A couple of years ago the only way to have an external stylesheet was by using the link element; the @import syntax was not recognised by most available browsers. That is not the case now.

Let’s refresh our memory about how to incorporate external stylesheets in HTML documents. Assuming we have a stylesheet named style.css, we can use the link element like so:

<link href="style.css" type="text/css" rel="stylesheet" 
media="screen">

Every CSS-supporting browser will recognise this. Note the media attribute: it is important to remember that if this is used, any value other than "screen" will make Netscape 4 ignore it. Since this is the only way of referencing an external stylesheet Netscape 4 knows, you probably want to avoid that.

The other technique is to use @import, which is done (ignoring media types for the moment) like so:

<style type="text/css">

  @import url(style.css);

</style>

Making use of the concept of cascading style sheets, it is obvious that we could do something like this:

<link href="nn4style.css" rel="stylesheet" type="text/css">

<style type="text/css">

   @import url(style.css);

</style>

More advanced browsers will get all the style information that is in the linked style sheet as well as all the information in the imported style sheet; where the same property is defined differently in the two style sheets, the imported sheet’s definition will be applied because, coming after the linked stylesheet, it is closer to the element to which the style is being applied.

This gives us a way to provide a stylesheet for Netscape 4 and a different stylesheet for better browsers; but it doesn’t help with separating browsers with very good CSS support from those with less good support, such as Internet Explorer. Let’s look at how to do this in practice, taking the three browser groups in turn from the top of the document.

Netscape 4

The use of a linked stylesheet (say, nn4style.css) to provide CSS information to Netscape 4 is simple enough, but there are other factors which need to be borne in mind when authoring a page which may be viewed in Netscape 4.

  1. Don’t attempt to apply styles to the body element: the rules are not properly inherited by the content of the body.
  2. In fact, don’t assume that styles are inherited from parent elements or that the cascade from other style rules will work.
  3. Don’t set style rules for table or tr elements, set them for th or td elements; don’t try to apply padding, margins or borders to table, tr, th or td elements — this does not work properly.
  4. While NN4 can handle basic CSS positioning, it won’t accept it applied to anything other than a <div>. This also applies to some browsers with rather better CSS support, so you need to use div elements for positioning anyway.
  5. Do not use inline style definitions (i.e. the style="property:value;" attribute in HTML tags) because this can seriously disrupt the appearance of the page in NN4.
  6. Netscape 4 calculates width percentage values with reference to the window, not the containing element. The same applies to padding and margins.
  7. Attempting to apply margin and padding styles to inline elements may cause serious problems. Additionally, margin-top, margin-bottom, padding-top and padding-bottom will only work properly on div elements.

One problem which you may encounter is the blue border on images used as links. The style rule border:0 (or variations of this) will not remove the border. A workaround which you can put in the NN4 stylesheet is to make the anchor elements containing images a particular class (e.g. <a class="image"...>) and apply this style to the class (assuming the page background colour is white):

a.image {
   color: #ffffff;
}

If the background colour is something else, replace #ffffff with the appropriate value. Obviously this trick does not remove the border, it simply makes it the same colour as the background — so if you were using a background image this would not be so effective; unfortunately color: transparent doesn’t work.

The most important point to bear in mind when writing a style sheet for Netscape 4 is to use the minimum of styling; the more you use, the more likely problems become. Do not get fixated on making the page look identical to the appearance in modern browsers with good CSS support: that is never going to be an option. You can, though, get a page which is recognisably the same page as in other browsers despite the differences: that is a reasonable target to aim for.

Internet Explorer & other poor browsers

Having linked a stylesheet with the information for Netscape 4, you then want to apply the stylesheet which will be used by browsers with fairly good CSS1 and fairly poor CSS2 support. This includes every version above 4 of Internet Explorer for Windows. Although this stylesheet isn’t only for Internet Explorer, let’s call it iestyle.css.

Putting this together in the document head, we’ll have:

<link rel="stylesheet" href="nn4style.css" type="text/css" 
media="screen">

<style>
  
   @import url(iestyle.css);

</style>

For browsers like this, you can use CSS-positioning — but you are still limited to using top and left for defining the position of page elements. Useful CSS2 techniques, such as p+p {...} for stipulating what should happen when one paragraph follows another (perhaps removing the extra line between them and indenting of the first line), probably won’t work. This still leaves a lot of powerful techniques available to get a pretty good-looking page.

The most important thing to remember is that every style applied in the linked stylesheet, nn4style.css, will still be in effect unless you override it in iestyle.css. Hence you might want to include this rule in iestyle.css:

a.image {
    color: #000099;
}

Or you might not, of course.

Mozilla & other very good browsers

As I said, no browser supports all of CSS2, but some browsers do a pretty good job with it. Mozilla is one of them, Opera is another. Internet Explorer 5 for the Macintosh is not quite in their class, but it’s close. The stylesheet — style.css — is imported after iestyle.css:

<link rel="stylesheet" href="nn4style.css" type="text/css" 
media="screen">

<style>
  
   @import url(iestyle.css);
   @import url(style.css) screen;

</style>

Using the media type when importing the stylesheet will hide it from browsers with poor CSS2 support.

One peculiarity of Opera may surface if users switch to “full-screen” mode (by pressing F11): your carefully constructed style information for good browsers may suddenly vanish. It isn’t at all obvious why this should be the case… until you learn that Opera, for reasons best known to themselves, have decided that while the standard browser view is the expected “screen” media type, the full-screen mode is projection. If this is a worry — although Opera doesn’t have a huge share of the market, and most users surely don’t run in full-screen mode — you can fix the problem like this:

<style>
  
  @import url(style.css) screen, projection;

</style>

Assuming, of course, you don’t want to provide a completely different set of style rules for projection media types.

Again, note that all the style information from nn4style.css and iestyle.css will be applied unless it is overridden in style.css. Because iestyle.css is likely to be more complex than nn4style.css, this will probably require more attention.

For example, in iestyle.css you may have this:

#menu {
     position: absolute;
     top: 3%;
     left: 3%;
     width: 18%;
     font-size: .86em;
     border: 1px solid #000066;
     background-color: ##cccccc;
}

This is a menu bar positioned to the left of the page, using style information which IE6 can understand. Suppose, though, that in better browsers you wanted to put it on the right of the page like this:

#menu {
     position: fixed;
     top: 3%;
     right: 1%;
     width: 18%;
     font-size: .86em;
     border: 1px solid #000066;
     background-color: ##cccccc;
}

It may be unlikely that you would want to do that, but this is an exaggerated example. It may well be that because of the way less standards-compliant browsers sometimes render page elements that you don’t simply want to specify precisely the same positioning and dimensions in iestyle.css and style.css. The problem you run into here is that iestyle.css positions #menu using left:3% and that is still applied to the document — so the menu bar’s position will not be where you want it in, say, Mozilla.

Of course, it would be possible to set the position of the menu bar in style.css using left:81% rather than right:1%, but if you want to place an element close to the right edge of the page it is more logical to use the right property if it is supported. What you have to do redefine the value of the left property. It doesn’t make a lot of sense to specify the position using both left and right, but you don’t have to. This will override the style information in iestyle.css and allow right:1% to take effect:

#menu {
     position: fixed;
     top: 3%;
     right: 1%;
     left: auto;
     width: 18%;
     font-size: .86em;
     border: 1px solid #000066;
     background-color: ##cccccc;
}

Summary

Caveats

It cannot be emphasised enough that the results of using CSS in Netscape 4 can be very unpredictable — even CSS using nothing but property definitions the browser should understand. On the whole, the more CSS you hit Netscape 4 with, the more likely it is that the page will fall apart. Sometimes you can get good results by taking the main stylesheet and stripping out every property Netscape 4 can’t handle — but this is by no means always the case; often you need to start with a blank stylesheet and build a very simple stylesheet bit by bit until you hit a problem (which may or may not be soluble). In the end, some problems are not soluble.

For example, in this page users of Netscape 4 may find that the first part of the main heading (CSS) is not rendered. CSS is enclosed in an abbr element — this improves accessibility for text readers, and every instance of CSS on the page is in an abbr element. Yet in the title, apparently because it is inside the h1 element, the text simply will not be rendered. That this is related to the browser’s poor CSS support can be seen by disabling CSS: the text CSS is now visible.

The choice I faced was to leave it as is and have a damaged rendering for a small proportion of users, or to remove the abbr element and fix the rendering for them but make the page less accessible to other users. Since the markup is correct I have decided to leave it as it is: it would be illogical to diminish accessibility to accommodate the deficiencies of a broken browser; but there is no solution which is perfect for everyone, something which is all too common when considering Netscape 4.

I have, by the way, been talking about Netscape 4 all the way through this as though it were a single entity. It isn’t. Netscape 4.0x versions — the last browsers to be distributed as the standalone “Netscape Navigator” — are much worse at handling CSS than the later versions distributed as “Netscape Communicator”. Even there, though, versions numbered only slightly differently may react differently when presented with CSS. Worse than that, versions numbered identically on different platforms may not respond identically.

I have not mentioned the remaining option in dealing with Netscape 4 browsers: not providing them a stylesheet. This will result in the document being presented with each page element being arranged, top to bottom, in the order in which they occur within the document; quite possibly the background colour will be Netscape’s default (and very unattractive) grey. This may be aesthetically unappealing, but it is completely usable: this may be the best (as well as least time-consuming) way of dealing with Netscape 4.

And in fact, this is the technique now in use here. The usage of Netscape 4 has declined to the point where it is simply not worth the effort attempting to provide it with CSS it can cope with. This is no bad thing. I still think it best to access the main CSS using the @import techique rather than the link element, purely because this will stop the CSS wrecking the site for the very few Netscape 4 users still out there. I think that is a reasonable approach, and as far as it is sensible to go now in accommodating Netscape 4.

You may have noted that I have not mentioned Internet Explorer 3, which is supposed to have CSS support (the first browser to do so, if I recall correctly). IE3’s CSS support is non-standard and buggy: the only thing to do about it is ignore it if you are an author, and disable CSS support if you are a user.

Further reading:


Site Meter
Valid XHTML 1.0! Valid CSS! Level Triple-A conformance with WAI guidelines