Cascading Style Sheets (Level One) Browser Intercompatibility
How I Achieve It
-by
Charles T. Low
-from:
ctLow Home
to:
CSS1 Canvas - CSS1/HTML Demo
-on this page:
Note:
This sub-site was last updated in 2004 April. Things have improved since then, and the particularly egregious older browser programs are no longer as common, so i) you don't have as much to worry about it and ii) much of the information on this site could probably now be considered of mainly "historical" interest.
Introduction
I would like to present a few simple solutions I have found to some vexing problems regarding browser incompatibility with Cascading Style Sheets, level one ("CSS1"). I have culled this information from various sources, and hope that this condensation will save others some of the time and aggravation engendered by this issue.
No current web browser program that I know has 100% compatibility with CSS1. I use these five:
- Microsoft's Internet Explorer ("IE") 5.5
- IE 4.7
- Netscape's Navigator ("N") 6.0
- N4.7 and
- Opera ("O") 5.02.
By far the weakest is N4.7 (and presumably other releases of version 4), to the point of being an embarrassment. Why they released it in such bad condition I cannot imagine. IE4.7 requires some "imaginative" workarounds too.
These are all the browsers I have at my disposal, on which to do testing, so goodness knows what problems older browsers cause. Also, I use WinME, Win98/Win98SE and Win95 - your mileage on other operating systems may vary!
For the amateur web page designer, initially thrilled to discover the versatility of Cascading Style Sheets (CSS), browser incompatibilities with the World Wide Web Consortium ("W3C") standards quickly become a major headache. More frustrating is to discover that the CSS level one specification, which is all I have used so far, was finalized in 1996. CSS2 followed in 1998, and CSS3 is under development. Granted, it takes a while for programmers to develop "compliant" programs, but pretty well five years since 1996, and we're still not there? This fact has wasted countless hours of my time, and I shudder to think how many thousands of other individuals have faced the same problems.
My only qualification is that I am an inquisitive person (also sensitive and caring, but that doesn't matter here) who has scoured the web and experimented into the wee hours trying to sort this out, in general spending far too much time peering into my cathode ray tube. I have been designing amateur web pages since around 1997, and if you're interested in seeing any of them, start at my personal home page. (I would be very pleased were you to have a look.)
Elsewhere on the web (see links below) you can find scads of other information about browser (in-)compatibility, but this effort represents my own personal distillation, from what can be a bewildering cornucopia of facts and figures, of the very basic modifications which have solved 99% of my browser CSS1 incompatibility problems.
Disclaimer: In presenting this information, I am trying to be helpful, but please use everything here at your own risk, and verify anything critical to you with more expert sources.
Online CSS references
This document assumes basic familiarity with HyperText Markup Language ("HTML") and CSS1. If you understand what's going on so far, you're in the right place. Otherwise, you need to learn HTML and/or CSS basics. Whatever your level of expertise, here are a few good places to look for pertinent information:
- Web Review
- Web Design Group
- W3C (they design the standards)
- -this page's HTML code: select "Source" on the View menu.
- -this page's CSS1 code.
- -my CSS1 Canvas page.
- -my CSS1 and HTML "graceful degradation" pages.
Upgrade your browser
The simplest thing would be to convince everybody to upgrade to the latest version of their preferred browser, but that doesn't happen for several good reasons, so backwards compatibility becomes a must. Some advanced web sites detect which browser you're using and then present you with versions of their web pages tailored to that browser. I am not (yet) in a position to do that, so have tried to write HTML and CSS1 code which will look good and work well on modern as well as older browsers. I'm not doing anything particularly fancy, so this document is by no means exhaustive. I have posted information elsewhere on where to find the latest browsers.
While we're at it, getting everyone a 17 inch monitor would make our web pages look better too! But, back to the real world...
Elegance vs. Graceful Degradation
One simple issue is that of elegance vs. "graceful degradation." The idea is that if the user can't or won't use your style sheet's formatting, the page should still display properly, albeit plainly. This is called "graceful degradation." Whether the concept matters to you will be a matter of personal choice, but at least some of what follows assumes that it does matter.
I keep two demonstration pages, each almost identical to the other except that one uses CSS1 and the other just plain HTML. Opening and examining them both illustrates (I hope) what I mean by graceful degradation.
Neither iteration contains any HTML formatting code whatsoever - all the "tags" are bare-bones (as also on this page), never using any block-formatting properties like "ALIGN" OR "WIDTH". CSS1 does it all. I don't even use a single TABLE anywhere. (I do allow myself inline-formatting properties such as "STRONG" and "EM", but certainly not "FONT.") Avoiding these tags is not easy! I don't necessarily recommend it - I'm doing it here mainly as an exercise, with no desire to evangelize. But the "no-tag" policy let's you see that despite the extra formatting provided by CSS1, all the content is still present and readable without it.
As a case in point, let me discuss "headings" ("Hx" tags), with which I trust you are familiar. With CSS1, we may want to take control over some of the browser's default settings for headings, modifying things like font, size, color, weight, style, margins, padding, line height, alignment, etc. Unfortunately, each browser does this differently. N4.7's implementation of CSS1, for example, runs adjacent lines of a heading text into each other, i.e. if the heading doesn't all fit onto one line, it doesn't give enough line height to prevent one line from from vertically overlapping the next. Also, it simply will not collapse the space around headings, no matter what your style sheet tells it to do, to the degree that more modern browsers will. This makes it impossible to place things predictably on the "canvas." (As I recall, IE3.x behaved similarly.) And if you customize your code for N4.7, it won't look right in other browsers. (And the browsers sometimes don't let you take complete control of header formatting anyway - and each browser is different!)
One simple way around this is to avoid using heading tags at all. (I don't necessarily recommend this - I explain why not soon.) In their place, you can construct what I call CSS1 "pseudo-headings" such as this:
P.head3 ( font-family: serif; font-size: 12pt; line-height: normal; font-weight: bold; font-style: normal; text-align: center; color: gray; margin: 0; padding: 5pt 0; }
Then this HTML code:
<p class="head3"> This is an example of a "third level pseudo-heading" paragraph. </p>
produces this substitute for a level 3 heading:
This is an example of a "third level pseudo-heading" paragraph.
Narrow your browser window to force it onto two lines, and see if it still displays properly (it should). So, problem solved? Not really. Compare this technique as used on the CSS1 demonstration page versus the HTML page to see why not. All formatting is lost without CSS1, the pseudo-heading degrading rather ungracefully to just plain text, whereas more conventional headings are functional, in their own way, with or without CSS1.
So, in this and many other ways, we often wish to produce HTML and CSS1 code which looks great, and positions things for us reasonably accurately on the "canvas," while degrading gracefully. (I hope that in the not too distant future, all browsers will exhibit excellent CSS functionality, and this page will become obsolete.) Attaining both of these objectives simultaneously continues to prove challenging!
CSS1 browser inter-compatibiity
So, that's what leads me here, to describe a few idiosyncratic tips about how to code CSS1 for browser inter-compatibiity. Let me know if you find it helpful, or have any suggestions.
My starting point will be the underlying CSS code which the W3C recommends as the basic standard for browser programmers. (Browser programmers are the guys and gals I'm complaining about - we're not them, we're HTML and CSS programmers, writing code for the programs which browser programmers have produced for us.) That W3C CSS1 code can be found on the W3C web site, and is supposed to represent the basic defaults expected of a CSS-less browser. If applied unaltered to most standard, non-CSS HTML web pages, this style sheet has (or should have) only a minimal, if any, effect on how they appear.
Following are the modifications I make to that "standard" code, to enhance CSS1 inter-browser functionality. Some of the topics of necessity overlap a bit.
Body font
Problem
I and many others find Times New Roman great in print but Verdana (or Arial or "sans-serif") better on a computer monitor.
Solution
Change the default font to whatever you prefer! Remember to leave a generic fall-back (e.g. serif, sans-serif, etc.) to allow for unavailable fonts at the user's end.
Line height
Problem
We are given a suggested line-height by the W3C of 1.1, but the problem here is in how this inherits. As will often apply in the following sections as well, how the various browsers deal with inheritance is a major (but not the sole) problem. N4.7, for example, seems to use "1.1" times the line-height for the default paragraph font size, not the current font size. Line heights should, of course, be calculated on the current font-size, so 1.1 times a heading's font size for a heading, 1.1 times a paragraph's font size in a paragraph, etc. Using the smaller paragraph line height for a larger heading font does not work - the lines overlap vertically.
A similar problem can occur with lists such as UL's. If the line height of a list item needs to be enlarged because of some inline element like an image, the default setting of 1.1 doesn't work. Subsequent item lines overlap terribly in N4.7.
Solution
Change the line-height from 1.1 to normal. Why this works I do not know, but it does. You can still specify margin and padding for headers until the cows come home, although N4.7 has a mind of its own and will largely ignore you. It's still a worthwhile thing to do for the effect you can create in other browsers, but you simply won't be able to display things as tightly in N4.7. (Get over it!)
Sizes
Problem
CSS1 offers us many units of measurement, but the way they are rendered is inconsistent among browsers. These include em, which equals one "font-size," px for pixels, ex for "x-height," pc for picas, in, cm and mm for inches, centimeters and millimeters, as well as pt for point. A point is 1/72nd of an inch, so I understand, although I sincerely doubt that it always works out that way on computer monitors.
Solution
Use pt for sizes. It provides the most stability among browsers. I found this information on ZDNet. Click on "Developer," then "CSS/Fonts", then "CSS - Relative Sizes of Text". The article discusses text sizes, but I have extended it to sizes of other things, and my preliminary observations are that it works well. I believe that as a rough guide, 12 point would represent a "medium" font size and 10 point would be "small." (This is "10 point.") In general, use a line height between zero and two points larger than your font size, depending on how tightly spaced you want your lines. (Using normal line height, as described above, is probably better - slightly less accurate, perhaps, than specifying individual line heights for each differently-sized item, but very convenient and it produces quite acceptable results.) Don't be shy about trying pt for things like border thicknesses, margins, paddings, and so forth (not yet extensively tested).
Using the point system for sizing does have the drawback of losing some or all of the flexibility of relative sizing in designing your web page. Also, as the user specifies smaller or larger text sizes, ones that you locked in with a fixed point size may just stay locked (IE is like this, not the others). Also, users will increasingly be accessing the Web from other than "conventional" computers, where fixed-size measurements may not work properly. But then again, using relative sizes like smaller and larger can backfire if you do multiple nesting - for example, put a paragraph inside a table inside a division, and in some browsers all of the smallers (which you may have declared multiple times to keep N4.7 happy) add up to microscopic. In others they don't - they inherit differently. The CSS validator at HTML Help generates a warning for every fixed point size used. So, many authorities advocate always using relative, not absolute, sizes, but there are pros and cons, just like everything else in life...
TABLE's
Problem
The TABLE feature of HTML does some things you just can't do elsewise. It's certainly the most convenient way I know to produce multi-column, aligned text (example), and is one of the few (only?) elements of HTML which allows such versatility of block-level formatting. You can make them narrow (WIDTH), toss them to one side of their container (ALIGN), give them a BORDER and make other blocks format around them. Try that with P or DIV! Doesn't work. Maybe it should, but it doesn't. (Even with tables, it still requires the HTML align property - if you know how to do it using just CSS, please holler. Read the section further along about floating before you do, though.)
Floating
Problem
The CSS1 float property still seems extremely quirky to me. It does not reproduce exactly the action of the HTML ALIGN property in all browsers. Some of this has already been discussed. If used way down at the bottom of a container such as a DIV, for example (see the "update" date at the bottom of this page), it does not stay contained, but runs on below the lower DIV border. This reproduces so closely among the several browsers that it may not be a bug - that may be how they want it to behave! (HTML's ALIGN is similar.) It seems it can also crash N4.7 completely (that would be a bug!), and so I have to feel very cautious about employing it.
Solution
Test your code! In many circumstances, you won't be able to use float. (At least, I can't always.) I substituted text-align for the update/links paragraph at this page's top and bottom (but it too is quirky in N6.0), and its effect won't always be the same as float, especially if you add backgrounds, borders and the like.
However, in N4.7 (again!), tables often (always?) slide under images which are right aligned (left-aligned seems OK), obscuring part of the text or whatever else is in the table cell. Tables in N4.7 malfunction in other ways too. This is very limiting, and is one reason that I used to get the occasional call from a friendly critic advising me that a page I had posted was a mess. It had looked OK when tested on my current, preferred browser! Not necessarily so elsewhere.
Other block-level elements, however, can certainly make full use of versatile CSS1 properties such as border, margin, padding, width, etc. So unless you really need the block-level alignment feature of tables, or multi-column functionality (also coming in higher versions of CSS and HTML), use something else, and avoid tables.
There's more! See the sections further along on block-level inheritance and on rulers.
Solution
Avoid tables. Where you must use them, check your pages carefully for the type of conflicts described - then you simply have to re-arrange them to work around this bug!
Block-level inheritance in N4.7
Problem
Inheritance in N4.7 is such that BODY font properties must be restated for tables (as well as for other block-level components). So, you have to repeat these BODY declarations for things like P, TD, UL, OL, DIV, etc. One option is just not to worry about it, and give up a little control - another is to avoid block-level elements to the degree possible (but that's no fun!). Note that we repeat font declarations on the TD element, not on TABLE. You'll find some things must be specified, in your CSS1 code, for one, and some for the other. The opposite obtains with lists: specifying on the LI element might not work when the UL or OL one does. I don't have a complete list - check the references given above.
Netscape seems to have claimed that the lack of TABLE inheritance was intentional, and conformed to original HTML specifications - except that it is pretty well cleared up in N6.0. (N4.7 was so bad about this that sometimes, font declarations would work for paragraph text, let's say, then for following table text [if so specified explicitly as just described], but then fail on following paragraph text - most frustrating!)
Solution
Test your pages in N4.x whenever possible. Reiterate all text-related properties as indicated above, depending on which ones your page uses.
A:[pseudoclass] IMG
Problem
Using A:[link|active|visited] IMG is simply more trouble than it's worth. N4.7 is the worst culprit, again, making little bordered boxes beside the images. Opera 5.02 doesn't apply this declaration at all. I just don't use it.
Solution
Avoid A:[pseudoclass] IMG. (The W3C calls this a "contextual selector," which is kind of cool - ya, too bad, it would feel good to use something with such an impressive-sounding name.)
Rulers
Problem
Elect me! No, wait, wrong kind of ruler. I like using rulers to help divide web pages up into logical divisions, and often I'll use thin rulers, perhaps lightly coloured, between minor divisions, and thick, dark rulers between major divisions. Only thing is, different browsers need different CSS1 commands. N4.7 doesn't recognize any of them (beyond the HTML ruler properties). Opera doesn't colour them without the background property, which then makes thicker rulers than the other two browsers.
Solution
Combine CSS1 and HTML code. This compromise works well enough:
HR.major { border-top-width: 5pt; height: 5pt; color: navy; background: navy; } HR.minor { border-top-width: 2pt; height: 2pt; color: fuchsia; background: fuchsia; } /* IE uses one thickness, Netscape t'other! */ /* background property for Opera 5.02 */
And then in the HTML:
<hr class="major" size="7"> . . . <h4 class="minor" size="3">
The HTML size property will be safely ignored if there is a conflicting CSS property (that's part of the "cascading" of "Cascading Style Sheets") - more on that later.
Another Problem
N6.0, regarded by many as the most CSS1-compliant browser yet, runs rulers right over laterally-aligned images. I have seen Opera 5.02 do this over a "floating" DIV, too. So, code like this sometimes works:
<img src="image.gif" alt="image" style="float: right; " align="right"> [Insert text here.] <hr>
but will sometimes - and I must admit, unpredictably sometimes not - draw the ruler right over top of the image, if the ruler isn't otherwise below the image's lower edge. None of the other browsers I've tested do this, including the horrible N4.7 - only N6.0. In the others, the ruler stops short of the image. (This is more of an HTML than a CSS1 problem, but I'm sticking it in here anyway, and one of the partial solutions just below is a CSS1 workaround.)
Solution
Avoid rulers below images. But this is really a pain. I often like a graphic or logo "aligned" in an upper corner of my page, for example, letting headings and text flow around it as HTML allows it do so beautifully. Then a ruler, visually separating the page's title and associated information from the more detailed content below, fits in there very nicely (example)-- but not if slices through your IMG. So, one way around it is to contain the ruler in another block-level element. On such thing is a TABLE cell - but then you know how I feel about tables. But this modification might work, and yet be almost transparent to non-offending browsers:
<table width="100%"><tr><td valign="top"> [Insert text here.] <hr> </td><td style="float: right; " align="right" valign="top"> <img src="image.gif"> </td></tr></table>
or
<img src="image.gif" style="float: right; " align="right"> <table><tr><td> [Insert text here.] <hr> </td></tr></table>
But then if the text runs on below the image, neither of these will allow text wrapping. I have also succeeded by using a list item:
<img src="image.gif" style="float: right; " align="right"> <ul> <li> List item one. <li> List item two<br> <hr>
This does not, however, work within a DIV or P.
Putting the HTML code <br clear="all"> just before the ruler used to work, but with IE6, can make the preceding text disappear (sheesh! can they make it any harder?)!. Also, with any browser, it often leaves a large chunk of white space where you don't want it.
Using a lower paragraph border via CSS1 code, instead of a ruler, works (except that it is completely ignored by N4.7), like this:
P.under { border-bottom: 5pt solid navy; }
So, there is no ruler rule - some solutions will be better in certain situations than others.
Padding, margins and width
Problem
These still haven't percolated through to all the elements one might wish. Especially with IE, padding doesn't seem always to function properly - it certainly doesn't spread things out the way the other browsers do! And especially IE seems to have difficulty placing the border where it's supposed to be, which is in between the padding and the margin (perhaps because it doesn't create the padding!).
What's more, eliminating or minimzing the use of padding and margins reduces or eliminates many of the bugs especially in the older browsers. Some of the problems described elsewhere on this page concerning text sliding under images, etc., may resolve if you don't specify paragraph margins or padding, for example. (The paragraphs will probably still have margins, based on the browsers' defaults.) Also, IE4.7 doesn't size DIV's within other DIV's properly - it seems to calculate the CSS1 width property on something wider than the parent's width, seriously confounding your artful efforts.
N6 doesn't appear always to recognize the top margin of a DIV (but often it does - I haven't discovered yet how to predict it). I often enclose the entire contents of a page in a DIV, to create what I hope is a pleasing display, and want a small margin at the top and bottom (and probably a wider one at the sides).
Solution
Be aware. That's all I know to say about this. Test your code in different programs, and make sure you're not doing anything awful in one of them. Mostly, you'll just have to accept some loss of control under some circumstances.
The IE4.7 DIV problem vanishes with this CSS1 code (not explicitly declaring a width), and still displays properly (assuming you want a centered block) in all of the other browsers I have tested:
DIV.whatever { padding: 10pt; margin: 20pt; }
For the N6 problem, I can simulate a top margin by declaring a top margin to the BODY element.
Inheritance
Problem
The most recent versions of the three browsers I have tested all inherit block-level properties fairly well. (We can expect older browsers to give us more trouble.) There are a few differences among the browsers, and some idiosyncracies or behaviours we might not expect.
Solution
Visit my CSS1 Canvas page for further details.
Test your pages. I'm really not in a position to list every idiosyncracy of every version of every browser. I consider myself fortunate to have a slightly older computer on which I never got around to upgrading N4.7, and I have uninstalled IE5.5 on it which leaves IE4.7 (for testing purposes). But working with what you've got available, display your pages on as many different systems and programs and versions of programs as practical, to make sure something disastrous isn't happening somewhere to your otherwise beauteous HTML and CSS1 code.
Validating code
Problem
How do you know at least that you haven't inserted something erroneous into your code? If your having a particularly stubborn problem with an HTML/CSS1 page, maybe you've just made some tiny, hard-to-find mistake somewhere.
Solution
Validate it. There are several places to do this, but currently I'm going right to the source, the W3C, and using their HTML and CSS validators. Very valuable.
Combining CSS1 and HTML formatting codes
Problem
What can you do if you're a pragmatist (not a purist) and you want your extraordinarily artistic CSS1 pages to degrade more gracefully than just to plain HTML?
Solution
Combine CSS1 with formatted HTML. For example, you can't give a border to a TABLE using CSS1 in N4.7. But you want a border, all the time! Including a plain HTML border accomplishes that. For CSS1-enabled browsers, any CSS1 declarations override HTML formatting, so you won't mess anything up by including both, like this (although the CSS1 code would most likely be elsewhere, rather than inline as shown):
<table style="border: medium groove navy; " border="2"> <tr><td style="border: thin solid fuchsia; ">
Similarly, you can add HTML alignment, borders, padding, spacing and so forth to whatever else you otherwise would, and these properties will be safely ignored if the browser has conflicting CSS1 ones. In light of my float problems (elsewhere on this page), I still find I often use ALIGN in my HTML code, for example, particularly for tables and images.
Other N4.7 woes
Problem
I have a feeling things will continue to pop up with N4.7 for some time. I won't repeat every quirk mentioned elsewhere on this page. Trying to add a little padding to hyperlinks (so that a the link's background color doesn't look so crowded around its text) messes up the diplay completely. I have found the first line of a paragraph disappearing under a right-aligned image (but not the first paragraph following the aligned image - the 2nd or 3rd) - but not subsequent lines! I have discussed TABLE's above. N4.7 is particularly sensitive to code errors - little things like a forgotten "</td><td>" (outside of any table) which the others simply ignore can completely crash it. Missing closing table cell and row tags ("</td>" and "</tr>") can disturb the formatting mightily - the other browsers interpolate them where required. I haven't figured out the float issue, mentioned elsewhere on this page, but under some circumstances (but not others - and which are which I haven't deduced), N4.7 malfunctons badly. Here's an odd one: a background image specified under the BODY element seems to work just fine, but if put under a DIV, it inherits down to every other element contained in that DIV - they should be transparent, and let the DIV's background shine through, but they don't. They start the image over again within each paragraph, sub-DIV, table cell, etc. (Sheesh!) A background image referred to by a CSS file must be in the same directory as the HTML file, not the same one as the CSS file (where it has to be for all of the other browsers), so you have to keep copies of your background image files all over the place if you use multiple folders all referring back to the same CSS file. Omitting the semi-colon from some of the CSS declarations - legal under some circumstances and not flagged by a CSS validator - crashes N4.7. I have had crashes related to A:hover, although repositioning this statement higher up in my CSS file cured it(!). BLOCKQUOTE CSS declarations have also been a problem.
No sense belaboring the issue except that we would like to avoid the problems N4.7 causes, so if you know of any other important bugs, let me know.
Solution
Avoid the offending issues to the degree possible. (Encourage everyone to abandon N4.7!) Avoid P padding and margins, and N4.7 paragraphs behave much better, wrapping correctly around laterally-aligned graphics.
Conclusion
Cascading Style Sheets give such wonderful functionality to web page design that it's a shame there is so much inter-browser incompatibility. In many cases it seems to me that it would have been better had they omitted trying to interpret certain declarations rather than render them so badly.
Nonetheless, with a little extra care, those amateurs among us who haven't gotten into the Java jive and don't know our CGI-BIN from our trash can, can still produce CSS1-formatted web pages which will display excellently on all modern browsers and adequately on recent ones.
The most recent expert opinion seems to be that N6.x possesses the most robust CSS1 implementation to date. You will note, however, that I have found very little to complain about with Opera 6.x (except that some web sites expect and only work with one of the two major browsers, although Opera claims to have a workaround for this), and over the years have found the Microsoft products to be the most functional (would it were otherwise!).
I hope that this contribution will make your CSS1 journey a little easier!
-by Charles T. Low
-from: ctLow Home
to: CSS1 Canvas - CSS1/HTML Demo
-initial posting: 2001-02-11
-last update: 2006-02-12