Home - About my pages Matt McIrvin mmcirvin@world.std.com

Colophon

My Cascading Style Sheet choices

The CSS (Cascading Style Sheet) that I use on these pages is the result of a long history of tweaks and decisions that go back to the age of the earliest CSS implementations. I've tried to make the design pretty and distinctive but low-key, somewhat book-like but with concessions to the Web. My CSS changes over time; the following describes the reasons behind my choices as of the time of writing.

Dealing with the bad browsers

Old problems

My first CSS was kludgey because I was trying to make it work well with the hideously defective Internet Explorer 3 and Netscape 4. These days I just try to keep most of my CSS out of those browsers. Basically all you can feel safe setting on IE3 or Netscape 4 are the following:

That's really about it. Just about everything else is broken in some horrible way. Most things will at least leave your page readable in Netscape 4 (unless you try to print it out!), but this is not the case with IE3.

Now, the usual cunning Webmaster's approach at this point would be to sniff on the user-agent string and serve different styles to different browsers, either through JavaScript on the client side, or with some sort of server-side include. However, I don't like these approaches very much; they seem overly complex and fragile, they are notorious for being tripped up by the introduction of new Web browsers, and I find repugnant the idea that I should have to mess with scripting or the back end just to get some CSS to work.

Instead, I use a trick that is apparently due to Todd Fahrner, though I learned it from Matthew Brealey. I have a very simple style sheet for IE3/Netscape 4, and a much longer one for other browsers. The first style sheet fetches the second one via @import. IE3 and Netscape 4 don't support this, so they will only see the first sheet. I can do fancy stuff in the other sheet and not worry about it breaking the terrible two. Apart from them the worst widely used CSS browser is Internet Explorer 4 for Windows, but the problems in that are much easier to deal with.

The only problem is that there are some very early Netscape 4 versions (pre-4.08) that crash when they encounter @import in a style sheet! These versions are so unstable that most Netscape 4 users upgraded long ago, but it's something to keep in mind. Really the only alternatives are to do something even kludgier like JavaScript or server-side browser sniffing, or to avoid using about 90% of CSS.

I've heard people complain that this method is now obsolete since Netscape 6 supports @import. These people are missing the point. It's good for this method that Netscape 6 supports @import, because Netscape 6 also does CSS correctly.

New problems

Given how good things were getting with recent versions of IE (especially IE/Mac), Netscape 6/Mozilla, and Opera, I had reason to believe that CSS authors were out of the woods: developers had learned their lesson and new browsers would come out with relatively solid CSS support if they had any at all.

Unfortunately this appears not to be the case, and the frustrating thing is that some of the problems are associated with browsers I think of as good guys for other reasons. I like iCab, for its customizability, its brilliant "smiley face" that validates HTML on the fly, and the support of some HTML 4.0 features supported by almost nothing else. I very much like OmniWeb 4, simply because it has the best integration into Mac OS X of any Web browser, and is also quite customizable in ways that give tremendous power to the user.

Both OmniWeb and iCab have recently released partial CSS1 implementations, and, sadly, both of them have Netscape 4-like defects with critical things like margin calculations that can ruin page layouts. OmniWeb's implementation seems less complete, which also limits the damage that bugs can do. However, OmniWeb has a serious omission: there is no off switch yet for author CSS, which makes it harder to deal with the problems that do occur.

I'm adopting a wait-and-see attitude toward these implementations. Software development is hard, especially for functions as complicated and subtle as those implied by even the CSS1 recommendation. In both cases, the authors freely admit that the CSS support is incomplete and needs work, and they seem to be working hard on it. This isn't a Netscape 4 situation in which the bad implementation is obviously going to be widely used for a long time to come. Therefore, I'm not going to tinker with my pages just to make them look good in those browsers.

I do think that both OmniWeb and iCab should have taken the approach that iCab wisely followed with its JavaScript implementation: make it user-switchable and leave it turned off by default until the support is really good. Unfortunately this was not done with CSS, which makes it an issue for page authors. My hope is that people using these promising browsers are savvy enough to understand the situation.

(Note added April 2002: OmniWeb has become popular among Mac OS X users, and deservedly notorious for what's become known as the worst CSS support on the platform. Version 4.1 beta 2, though, improves the situation considerably. It's still got a long way to go. I'd say that it's gone from a Netscape 4-like level of support to something more comparable to IE4/Windows. But it's definitely now better at CSS than iCab, whose buggy box model implementation is responsible for the gigantic margins and drunken line spacing visible on many of these pages. On the other hand, iCab does let you turn off CSS.)

(Note added November 2003: Things are looking up. The latest version of OmniWeb uses the WebCore layout engine built for Apple's Safari (which in turn is based on Konqueror's KHTML component). This is not quite up to the level of Mozilla's Gecko, but is very close. Meanwhile, Safari itself has captured an enormous chunk of the Mac market, and Gecko-based browsers and IE/Mac have much of the rest; the less standards-compliant browsers are also-rans, and the rise of Mac OS X seems to have finally put an end to Netscape 4.x's reign as a leading Macintosh browser. Good times. Unfortunately, IE6 on Windows isn't quite as much of an improvement over IE5 as it should be, but you can't have everything.)

Text

Text and background color

I've gone for high contrast throughout, not just to help people with color blindness and low vision but to help people with normal vision too. Whether they realize it or not, nobody has an easy time reading text with low brightness contrast, and the brightness differences between Mac and PC displays, and between displays with different settings viewed under different conditions, make it all the riskier to try.

The general rule with Web color is that if you set a background color for something you should set a foreground color as well, and vice versa, so as to avoid bad interactions with user settings. So I'm stuck with trusting browser color settings (which sometimes default to ugly gray backgrounds, and which users have gotten used to not changing because most pages do it) or actually making color choices. As a tinkerer I naturally end up setting the colors.

Whether dark-on-light or light-on-dark text is easier to read is something that provokes passionate arguments. What the participants often fail to notice is that the light-on-dark proponents are frequently working in dark basements and the dark-on-light fans in brightly lit offices. (Old-school hackers tend to like dark rooms in part because in the olden days all video display terminals were light-on-dark. I know guys who specifically request the disabling of all lighting over their cubicles because they like green-on-black text windows.) In general, you want the brightness of your display to be comparable to that of the display's surroundings. I've chosen black on white because I prefer it and because it is somewhat less likely to interact badly with the default settings of most Web browsers.

I depart from the mostly monochrome scheme for non-link colors for the case of BLOCKQUOTE elements that are used to indicate Usenet quoted text. To make it easier to follow complicated multiply-nested conversations, I use alternating brown and dark green coloring for the nesting levels. This was inspired by the behavior of some newsreaders that color quoted text differently.

Font

However, I do not set the font family or font size used for ordinary paragraph text. This makes it as easy as possible for users to adjust these things if they find my text hard to read. Other font sizes are set in relative units so that they will rescale even in Internet Explorer versions that don't let you rescale absolute-sized text. Thus I sidestep the whole PC vs. Mac vs. Linux font-size problem, adapt gracefully to people with low vision, and generally make people happy. If the font looks too big or too small, just change it.

Headings

The gray "outdented" headings, and the right-aligned subtitles that match them visually, were one of the earliest CSS tricks I did on these pages, when I was working with IE3 and Netscape 4. Now the outdenting is not even visible on those browsers, because I moved that effect to the imported part of the style sheet, for various reasons. I was just trying to do something a bit unusual yet dignified-looking; I may have been partly inspired by the Lynx treatment of H2 and higher. Since then, outdented headings have become a common thing on Web pages that use CSS. You can indicate a hierarchy with them easily, and their inherent asymmetry can be attractive if the page is laid out in a balanced way.

When text is big, you can get away with more. Originally I had three different shades of gray that got progressively lighter for H1, H2, and H3 elements. I cut it to two to make absolutely sure that I didn't lower the contrast too much for headings that were going to be pretty small. I still think the use of two shades of gray looks nice.

On the off chance that you've got Gill Sans installed, the headings are in Gill Sans, which is one of my favorite display faces. Most people will probably see them in Verdana, a font that is in some ways similar and is a fine font in its own right.

The right-aligned subtitles are actually a class of paragraph, not a heading (from a structural perspective this is probably the best way to handle them). I also have a special class called impactor that I use to make some short H1s larger than usual. Originally the H1.impactor was truly gigantic ("impactor" meant "make this like unto a dinosaur-killer asteroid"), and I used it mostly for comic purposes, making a word or two fill half of the screen. When it was pointed out to me that font sizes that big could actually crash some browsers, I toned it down, which also made it more useful. It's still pretty big.

Links

For now I've chosen blue unvisited and dimmer purple visited links because those colors are familiar and understood by most users.

There seems to be a general consensus today that Jakob Nielsen is wrong and you can use whatever link colors you want. I agree with that more or less, but I do think that some possible choices are not good, like making them all the same color as the text, or making them unreadable against the background, or choosing colors such that the visited links look like they ought to be unvisited and vice versa. One page about CSS at the W3C used to use purple for unvisited links and blue for visited ones! (It's fixed now.)

Underlined vs. non-underlined links are another controversy. People with a typographic background tend to find underlines unbearably hideous, and they are almost never used in books. So the first thing these people do when making a Web page or setting up their own browser is to ask how to get rid of link underlines. Personally I think that the fact that underlines are not used in ordinary typography makes them splendid as a choice to indicate something that never appears in print, like a hyperlink. They're also another level of color blindness support.

I've decided simply to not specify anything about link underlining. It's up to the user.

The hover effect is a pure affectation. I doubt that it does anything good from a usability perspective but it looks cool without doing any real harm. For a long time, I did these hover effects using CSS2 dynamic pseudo-class combinations such as A:link:hover. I had to make them rather subtle because of a bug in Opera that applies such styles to all links, not just the hovered ones. (This is sometimes claimed not to be a bug, since Opera makes no claim to support dynamic pseudo-class combinations. However, in this case it is still a bug in Opera's error handling: it should ignore unsupported selectors rather than applying them wrongly.)

Recently I've given up any hope that this will ever be fixed in Opera, and reverted to the stupid old A:hover method, which allows me to make the hover effect a little more overt, if less versatile.

Margins and layout

Right and left margins

My margins have evolved over time, gradually getting larger and larger. There's a certain design tension here. On the one hand it's traditionally considered detrimental to make text too wide, and many, perhaps most people read the Web with a full-screen browser window. This leads to a temptation to set the text width.

On the other hand, the CSS methods supported by most of today's browsers only let you set widths either not at all or in a too-rigid way, so that if the browser window is narrow, it won't flow to fit.

My compromise is to set generous margins in percent units. The text still gets a bit uncomfortably wide if the browser window is wide, but at least there are nice big margins in that case, and if you make the window narrow the margins shrink to fit.

Then, for the few, very modern browsers that support it (Mozilla/Netscape 6 and Opera, for instance), I use the CSS2 max-width property on paragraphs and similar things, set in ems, to limit how wide the paragraphs can get relative to the font size. I use max-width, not width, so that the text will flow to fit a narrower window if necessary.

The margins on BODY are about as large as they can be given a problem with "outdented" page elements. While the correct behavior of percent widths in CSS is to calculate them with respect to the containing block, in Internet Explorer 4 and 5 on Windows they are instead calculated with respect to the browser window, and in OmniWeb they are calculated with respect to the whole screen. This can lead to the "outdenting" pushing things right off the page if percent widths are used. So I have to tone down the use of negative margins on headings. The narrower BODY is, the more of a problem this becomes, because the difference between the various calculations becomes larger.

Into the margins

(Note added September 2002: Much of the following section is now obsolete, because an infuriating bug in Internet Explorer 6 for Windows tends to amputate things with negative right margins, and I've had to get rid of most of them.)

I've already mentioned the "outdenting" of the headings to varying distances into the left margin. This looks nice and illuminates the structure of the document, but its asymmetry leads me to want to balance the page composition somehow. Consequently there are things that extend toward the right as well.

The most obvious are the page navigation header/footers, whose borders extend to the right but not to the left. Originally (because they date from my very earliest Web pages, written when nobody knew better) these things were just raw text and links in the body of the page, set off by horizontal rules below the headers and above the footers. I wanted the horizontal rules to extend some distance into the right margin but to end abruptly at the left margin. This looked smart when it worked, but it turned out to be extraordinarily difficult to achieve because of the wildly varying renderings of horizontal rules in different CSS-supporting browsers. In particular, I could never get the things to end at the left margin in Internet Explorer on Windows, no matter what I did.

When Netscape 6 would do what I wanted in bugwards-compatibility mode but not in correct-rendering mode, I began to suspect that I was approaching the whole issue incorrectly. I had been a bit nervous anyway about the possibility of future problems with having unenclosed text in BODY. So I took out the horizontal rules and made the headers and footers into a class of DIV. I could have gotten my original design by making two classes and putting bottom borders on the headers and top borders on the footers, but decided to change the look a little instead.

I was going to give them a different background color but couldn't find anything in the browser-safe palette that satisfied me (the lightest gray was still too dark for a good-looking background, and the paler colors all clashed with the rest of my design).

That left borders. I played around with different border configurations until I found something unusual that looked good to me.

The varying thicknesses are reminiscent of musical notation, and also evoke a vaguely embossed effect while not being too literal about it (as the 3D border styles would be). I use different border styles on the pages that are supposed to look different, such as the blue-sky pages and the Kibology index page.

I also have right-floating images that extend into the right margin, and right-floating links back to tables of contents. Because I use negative percent margins on things enclosed in BODY, I've had to moderate the extent of right floating somewhat to get around problems that Internet Explorer 4/Windows has with calculating percent margins (they tend to be calculated with respect to the browser window rather than the containing block). I also have to limit my use of these somewhat because of a strange bug in IE5/Mac that can mess with the margins of paragraphs in a DIV that flow around a floating element defined outside the DIV, but with some care this is not much of a problem.

Paragraphs

From my earliest CSS days I've flirted with book-style indented paragraphs. This is another controversial issue. The W3C actually tells you not to use them, apparently on the philosophy that indentationless paragraphs with wide inter-paragraph leading are so familiar on the Web now that anything else would be confusing. I don't actually believe this, in part because so many commercial Web sites do other kinds of paragraph formatting in various ways.

The traditional rule among typographers is that you should have extra space between paragraphs or indented first lines, but not both, and in early, bad CSS implementations I couldn't get rid of the extra space between paragraphs. For a while I had considerable amounts of extra leading and indentation on first lines, until a typographer friend told me to stop it.

When I finally could do what I really wanted (at least on newer browsers), it turned out that the traditional book formatting-- about an em of indentation, and no extra leading-- made paragraphs a bit hard to distinguish on-screen, maybe because the paragraphs could be so wide on a wide window, maybe because of the extra general difficulty of reading things on CRTs as opposed to print. The first-line indentation also messed up a lot of things that I did with isolated paragraphs, and there was annoying extra markup I had to do to get around that.

Eventually I came up with something that seems to work pretty well; it involves a small amount of extra markup, but the markup is more or less structural rather than pure hackery. My default paragraph formatting has no first-line indentation, and substantial leading between paragraphs. However, I also have a special DIV.text class which signals a region of book-like text. Within such a DIV, there is paragraph indentation (a bit larger than you usually see in books), and a much smaller, almost subliminal amount of extra leading between paragraphs, just to give the reader a little more help seeing the paragraph breaks.

DIV.text itself gets generous vertical margins, smaller on top (so that headings are visually grouped with succeeding DIVs) and bigger on the bottom, so that I can use these blocks to group text into sections separated by more white space. I also use the CSS2 :first-child pseudo-class to eliminate the indentation on the first paragraph of one of these DIVs. This is not universally supported, but it really doesn't matter much if it isn't.

The markup gives me a considerable amount of flexibility to change my text formatting in the future if I want to.

More out of a will to tinker than anything else, I use the float property and :first-letter pseudo-element to do a drop-cap effect, that is, a giant floating first letter that visually matches the H1 headings. A little of this goes a long way and it can be silly-looking if overused, so there's a special paragraph class for this sort of thing and I only use it infrequently, if at all, on any given page.

The vertical formatting that I get for these drop-caps is different on Internet Explorer and Mozilla/Netscape 6 (something to do with variations in the handling of extra space to allow for accent marks). For a while I had the styles tweaked to make the IE rendering as good as possible, but the result was unacceptable on Mozilla, so now it's tweaked the other way, which is not quite so bad-looking on IE (also the CSS coding is more logical this way).

I've experimented with using :first-line to put the whole first line of such a paragraph in small caps, but this has certain small but annoying glitches on IE5/Mac (links in the first line end up disguised as plain text until the mouse rolls over them, for instance). I'm not sure it's such a good idea for these pages anyway. A better thing from a traditional typography perspective would be just to do the first few, carefully chosen words in small caps, but that necessarily involves more markup, and at this point my laziness kicks in.

Lists

List formatting has been a headache for me for some time. I think I've finally got it right. In my earliest CSS days I put margins on individual text block elements instead of on BODY, so lists presented a particular problem: if I gave lists or list elements a substantial left margin, nested lists would use multiple copies of the left margin and come out all wrong. So I stayed away from setting list margins, and lists tended to be shoved up against the left edge of the window even when paragraphs weren't. (I think I tried using descendant selectors to fix this and had trouble getting them to work.)

I eventually figured out that margins on BODY would sidestep that problem, but there was still a baffling Netscape/Internet Explorer difference: I could set the indentation by messing with margins on IE but they seemed to be added to the default on Netscape 4. I just chalked it up to another Netscape 4 bug and lived with it until I discovered how to exclude styles from Netscape 4.

Then I discovered that the same thing was happening in Netscape 6. Obviously I was missing something.

Then I read a Usenet post by David Baron that explained everything. It has nothing to do with the rendering of CSS itself, but rather with the default user agent styles that produce the default list rendering. I'm not sure about Netscape 4, but by default, Mozilla/Netscape 6 implements list indentation as padding, whereas Internet Explorer implements it as a margin. I was changing the margin without doing anything to the padding, so on Netscape 6, its default padding and my margin added to increase the list indentation over what I expected.

So if you want to play with the size of list indentation on UL or OL, you have to explicitly set both the left padding and the left margin. You can just set one to zero and use the other one. It doesn't matter which you use under ordinary circumstances, though in more complex cases you might actually care about the difference between margins and padding (it will make a difference for things like borders and special background colors on sub-lists, for instance).

I also put tiny vertical margins on inner nested ULs and OLs, which produces a subtle grouping effect that I like.

Valid HTML 4.01! Valid CSS!
Last modified November 16, 2003
Home - About my pages - Top Matt McIrvin mmcirvin@world.std.com