Taking our struggle with CSS font sizes public

Those readers not interested in web design issues, please pardon this post. For the rest of you, the following is a series of posts I made on the corporate intranet at work. We’ve been struggling with CSS font-size issues. It’s nothing original, but it is my hope that posting the explanation of the problem and one (of many, I’m sure) potential solution I wrote for my co-workers might be of help to others dealing with the same issues.

I’m also interested in feedback on the techniques we used. What did we miss? I’ve tested across a wide range of browsers, but if you notice any weirdness – please let me know.

My first post was an explanation of the problem – basically written so I could straighten it out in my head:

Posted to the silverorange Intranet by Steven Garrity
– January 3, 2003

We’re having some difficulty with font size issues with CSS and I thought it might be helpful to lay out everything we’ve been talking about in one location.

First, some history. We are using CSS percentages (eg. font-size: 75%;) to do font sizes on most of our current sites. We discovered last year that some Mac browsers were inheriting the font sizes recursively (since we put font-size: 75%; on all [td] tags, any table in side a table would be 75% of 75%, eventually getting to the point of being ridiculously small.

We couldn’t replicate this Mac browser inheritance issue ourselves, but it is documented, so we now sniff out all Mac browsers, and all Netscape browsers (on any platform) and show them pixel-based font sizes (eg. font-size: 12px;).

Pixel font sizes are by far the most reliable font sizing technique across all browsers, but unfortunately, none of the IE/Win browsers (including 4, 5, 5.5, and 6 – basically everyone on the internet), allow the user to resize fonts specified in pixels. This is really shitty – it was on Jakob Nielsen’s Top Ten Web-Design Mistakes of 2002.

Some browsers, like all mozilla/gecko-based browsers and Opera, allow the user to resize any fonts – regardless of how they are specified (including pixels). However, the majority of web users are running IE 5, 5.5, or 6. So pixels are easy to work with – but limit IE users from resizing.

The solution we have on most of our live sites right now (Horton Brasses, NovaScotian Crystal, The silverorange Intranet, etc.) works ok (percentages for smart browsers, pixels for dumb browsers). Any kind of browser sniffing is messy, but it works.

The trouble came when we started the move towards XHTML 1.0 (from HTML4.01). Using our current percentage font-sizing technique, if you change the DOCTYPE from HTML4.01 to XHTML, in IE 6, things go wacky. All of the sudden, IE decides to use the inheritance model correctly (which sounds good, but we were taking advantage of it’s weakness in this area – serves us right for leaning on bugs).

So, to make the move to XHTML, we have to figure out a different way to do font sizes. This really sucks, because we are very close to being XHTML compliant – it wasn’t nearly has hard (other than this issue) as we had anticipated.

Here are the options as I see them, let me know what I’ve missed:

  1. Switch to pixels entirely
    This would be a breeze from our perspective, but we would be locking font sizes for squinting IE users everywhere. We could make a font sizing widget in the pages themselves to resize, but I’ve always hated those.
  2. Stick with HTML4 for now
    We don’t have to move to XHTML. Stay with HTML4 would let us continue with our current tried and true font sizing technique.
  3. Avoid nesting of classes
    Inheriting percentage sizes only becomes and issue when you nest classes (or put classes on items that get nested themselves, like [td] tags). Wired News uses this technique to create a fantastic CSS layout with flexible font sizes in all browsers. This is my preference so far – however, it involves some annoying reworking of the way we use classes to avoid nesting.
  4. Use CSS font size keywords
    CSS has keywords that work much like the old [font size=”-1″] HTML tags. These work well, except for an inconsistency in IE5 and IE5.5 – but there is an elegant hack to get around this. Keywords don’t inherit – so a small inside an x-small is the same as outside. Sounds good – however, the default sizes aren’t great. For example, you can’t the equivalent of the 70% Verdana we use so widely (here on the Intranet, for example).

Ok – that’s the state of the union address on font size issues. I wanted to write it out to get all of us and I all on the same page – but I also wanted to write it out to help sort it out in my head. What a mess.

I might post this publicly (linked from aov, maybe) to see if we can get any helpful feedback, but I doubt it. [note: I thought I’d leave this in to show how resentful I am of all of you morons when in private 😉 ]

I think our best bet might be to follow the lead of Wired News (using option 3 in the list above). They’ve made a wicked site with out inheritance issues anywhere. However, this would prove to be very time consuming on existing sites. Maybe keep the current sites at HTML4 for now, and start our next site (and update small, easy-to-convert sites, like silverorange.com) using this technique and XHTML?

Bah.

Then, after some sleep and a night of feverish delieum battling the flu, I posted this possible solution:

Posted to the silverorange Intranet by Steven Garrity
– January 5, 2003

My subconcious brain has been working on this problem all week. Now, I think I have a potential solution for our CSS font sizing issues. This proposal is implemented on the stage silverorange site. Please report any weirdness. I’m going to do more testing before going live, but so far so good. Here’s what I’m doing:

  • I’ve moved from including the styles from a PHP file do doing the browser sniffing outside the CSS file. This allows us to include actually .css files rather than embedding the CSS in the HTML (browsers can cache the CSS – saving time and bandwidth).
  • I’ve simplified the browser sniffing. We were sniffing out Netscape 4 and below and all Mac browsers and showing them Pixels rather than Percentage font sizes. Now I’m only sniffing out NS4 and below (I’m not longer sniffing out Mac browsers). The trouble on the mac was with inherited percentages – and I’m not using them anymore.
  • There are three CSS files:
    • All browsers:
      • core.css – this file includes any styles (or part of styles) that are safe in all browsers
    • Netscape 4 (and below):
      • dumb.css – this aptly named file contains Pixel font sizes and a few other variations (line spacing is smaller, etc.)
    • All browsers other than NS4 (and below):
      • smart.css – this file is includes the combination keyword/percentage font size solution described below
  • Font size:
    • Netscape 4 and below sees only pixel font sizes – if we decide to ditch Netscape 4 at any time, we can lose all browser sniffing for stylesheets!
    • For all other browsers (on all platforms, including the mac), I’m using the Wired News solution: Declare keyword (small) font size as the base font size (for [body], [td], and any other key containers)
    • IE 4, 5, and 5.5 make the font size keywords one step larger than every other browser in the universe. There is a hack called the ?box model hack? that gets around this.
    • This base keyword font size is the basic full size Verdana used as the body text.
    • Any other font sizes (titles, and the beautiful smaller Verdana text used often on the site) and sized as a percentage of the keyword base font. These styles are never nested, meaning there are no inheritance issues.
    • This means that it you want the base font size (full size Verdana), then no style is needed at all (as it’s the base font size for the document).

I’ve done a bunch of testing and haven’t found any cracks in this method yet. However, dealing with the browsers is voodoo, so I’m going to do a bit more testing before implementing.

What separates this solution from the options listed in my previous post on the subject (above) is that I hadn’t thought of using CSS keywords as the base font size setting.

The solution discussed in this second post is now implemented at silverorange.com. Please let me know of any issues.

 

12 thoughts on “Taking our struggle with CSS font sizes public

  1. Allison, while the font sizes here on AoV aren’t really what I’m talking about – it appears to me that the default font size in Mozilla is 16 pixels, which seems to render the fonts at a reasonable size. That said – the Georgia font and size I use here is a little hard to read when smoothed on OS X. I’ll try to address this in the next version.

  2. Is there any reason you haven’t looked at ems for relative font sizing? They work very much like percentages (1em is equivalent to 100%, 0.8em is equivalent to 80%) but importantly do not suffer from the recursive inheritance problem. My favoured solution for font sizes these days is to set the basic font size for the document using keywords (and the box mdoel hack to knock older versions of IE in to line) and then set the size of headers, footnotes and so forth using ems (relative to the normal text size).

    Another useful trick I have found is that, while verdana at default size (with no font sizing applied at all) loks pig ugly, Georgia at default size actually stays quite attractive. Most designers hate the idea of leaving the font size as the browser4 standard but I have found that, provided you are using Georgia or another font that looks reasonable at default size, it can save an awful lot of hassle.

  3. Simon: After testing the idea of using ems for relative font sizing we found an inconsistency between html and xhtml.

    When you claim that em does “not suffer from the recursive inheritance problem” was the doc type of your site xhtml?

  4. Instead of browser sniffing for old browsers, use a method of linking the stylesheet that they don’t understand. They’ll ignore it, and smart browsers will use it.

    Load all your dumb styles in core.css. Then override each of those in smart.css. At the end of core.css, add the line
    @import “/path/to/smart.css”;

    When smart browsers read core.css, they will read in smart.css as well. Older browsers don’t understand @import and won’t even know smart.css exists.

  5. I try to stick with ems nowadays, often via @import, and towards the end of development bolt on a pixels-only style sheet for non-DOM browsers via JavaScript.

    Ems only become a nightmare with heavily nested tables, which are best avoided anyway. You can use descendant selectors (e.g. “td p {font-size:1em}” ) to bump nested font sizes back up to normal size where needed, that works fine.

    So if you’ve got lots of nested tables stick with pixels, otherwise use minimal markup and ems.

  6. Good points Adam and Matt. We’ve stuck to the server-side browser sniffing for NS4 for now because we’re using it for a few other issues (form input sizes).

    Can any one explain the difference between ems and percentages? From what I can gather, in IE6, when in XHTML ems don’t inherit, but in HTML4, they do. Percentages seemt to do the exact opposite (inherit in XHTML, but not in HTML4). Any other key differences?

  7. Steven: Yes, I do everything these days in XHTML 1.0 Strict with a doctype that kicks browsers in to standards compliance mode. I didn’t realise there were any inconsistencies between HTML and XHTML with that regard – thanks for pointing that out 🙂

    The main difference between ems and percentages comes when you start using them for widths/height/margin/padding of a block. 5em means “5 times the height of a letter within this block”, while 500% would mean “5 times the width of the containing block” – they have very different meanings. Using ems for this kind of measurements is often a good idea as they will resize when the user increases/decreases the text size setting of their browser.

    There is a note about this on the CSS-Discuss wiki: http://css-discuss.incutio.com/?page=UsingEms

  8. Just my very humble two cents, being only an amateur, but I’ve always stuck with pixels ala Zeldman’s Give me Pixels or Give me Death. When it comes down to a disagreement between crusty Neilsen and forward-thinking Zeldman, I usually go with the latter.

    That being said, you are still not limited to fixed text sizes. Zeldman himself uses what I believe to be a tasteful “widget” for text styling on his page, which also happens to validate as XHTML 1.0 – serving your original purpose.

    So with a little swallowing of pride on the widget discrimination, you get the best of both worlds. I call it the Ockham’s razor argument.

  9. Another ‘spanner in the works’ – it appears Firefox is rendering % font sizes smaller than Firebird, Mozilla, Opera or IE.

  10. Does anybody but me think this “font size on web pages” problem is insane, unreasonable, a problem that never should have happened in the first place?

    The very essence of the web is words on a monitor; flashing lights and whirring gears are strictly secondary. And yet the very hardest thing to do is put legible words on a page–or words that are legible for all users.

    When a problem appears insoluble, then the real solution is always one step earlier. In this case that “one step” leads not to webmasters, but to the browsers themselves.

    It can’t possibly be so hard for Microsoft and Netscape to make uniform font sizes that will respond to resize commands in a uniform way. What on earth can these people be thinking?

    – Alan Atkinson –

Comments are closed.