BeeBen's Web Programming PagesBee

Please note that these pages date from 2003 and are near prehistoric in internet terms. It was good stuff when it was written, but old hat now.

These pages not maintained and I no longer deal with queries about them. They remain here for historical interest.

Graceful Degradation

Graceful Degradation is the principle that a web page should be coded in such a way that if a browser cannot cope with something in it the page can nonetheless be displayed in a simplified form.

Ensuring graceful degradation is the essence of quality web programming. You have no idea what kind of devices people will use to access your web pages—a PDA? a braille browser? an audio browser? a text browser? a mobile phone?—, but there is a duty upon you as a good citizen of the Web to ensure that they are accessible.

XHTML and CSS2 go some way towards helping us to write pages that will degrade nicely on less capable devices. The separation of content and presentation allows people to access your content even when they can't see the presentational aspects. XHTML and CSS are described below.

A further requirement for ensuring graceful degradation is making very careful use indeed of client-side programming such as Javascript, Java, and abominations like Shockwave Flash. Use these things if you must, but please provide an alternative!


XHTML 1.0 Strict

My pages used to make heavy use of tables and other HTML constructs purely for layout. Although they validated as HTML 4.01 Transitional this was nevertheless ideologically unsatisfying and contrary to the spirit of graceful degradation.

The future of the web lies in XML. One instance of XML is XHTML which looks very similar to, as is backward-compatible with, HTML. A characteristic of XML is that it should mark up only the semantic content of documents, leaving their presentation entirely to the user-agent, which may be a visual web-browser, an audio web-browser, a database, or some device not yet conceived of.

So, I've expended a certain effort in making most of my pages XHTML 1.0 Strict compliant. It involves removing essentially all formatting from the documents themselves and instead placing it in the style-sheet. Note that "strict" compliance is much harder to achieve than "transitional" 8^). For an encore, although XHTML does not demand it, I've also removed most of the tables that were previously used only for layout.

One application that has immediately benefitted from this approach is the M'Cheyne Bible calendar, which is now easily viewable with PDAs. This was far from the case with the original table-based version with lots of inline formatting. The PDA simply ignores the stylesheet and can easily display the much simplified HTML. This is a real example of the importance of graceful degradation as described above.

The tidy program is a useful tool for doing the donkey-work of converting old HTML pages into XHTML, at least under Linux. I use it as follows,

tidy -wrap 0 -asxml foo.html > bar.html

The -clean flag is also useful when working towards Strict compliance



CSS2 (Cascading Style Sheets, version 2) goes hand-in-hand with XHTML. If XHTML is used to mark up the semantic content of a page then CSS can be used to format it in creative ways. As an example, the mechanism for changing the skins for the M'Cheyne calendar is almost entirely implemented by switching between different style sheets. Contrast, for example, the Rich style and the Grey styles. The underlying XHTML is very nearly identical, but the final appearance—if your browser supports CSS2—is very different.

The best ways to learn about style-sheets are to read the CSS2 specification and to look at other people's style-sheets. For example the style-sheet for my homepage, or the style-sheet for this page.

The @import technique

Or, how to be nice to Netscape 4.

We need to think about graceful degradation in dealing with CSS2 too. Most modern visual browsers can cope with most of the features of CSS2, but they all have their quirks. (There are various techniques for working around buggy implementations of the "box model" for instance. I haven't really bothered to deal with this: I test the pages in a range of browsers, and if it looks "good enough" then I leave well-enough alone.)

Unfortunately, older browers, such as the venerable Netscape 4.7 series, can't cope with CSS2. In fact even Netscape's CSS1 implementation is so buggy that working around the problems becomes a real pain.

In the case of CSS2 one way to work towards graceful degradation is to employ the @import technique. The idea is that (most) non-CSS2 browsers ignore the CSS2 @import directive, so we specify a simple style-sheet that all browsers can cope with in, for example, global_ns.css, and we import global.css, the CSS2 style sheet, thus:

<link rel="stylesheet" href="/global_ns.css" type="text/css" />
<style type="text/css">
@import url(/global.css);

Non-CSS2 browsers, such as Netscape 4.7, will not import the global.css style-sheet, and so will not become confused. You can see the effect of turning off the style-sheet for this page (ie. what Netscape 4 users see) by choosing the skin "none" from the "Skin" select box.

Pretty printing

One of the great new things CSS2 brings us is the @media selector. I have used this to provide printer-friendly versions of pages in various applications I have written.

It's very easy! First wrap everything you want to appear on the screen but not to be printed (for example, select boxes, text input boxes etc.) in <div class="noprint"></div> tags.

Now in your style-sheet put a section as follows,

@media print {
    .noprint { display: none; }

This section will be read only when a print medium is selected, i.e. when you are doing a print preview in your browser or an actual paper print, and it will thus hide all the things you don't want to be printed.

I've used the technique on this page to get rid of the sidebar and navigation and to format hyperlinks as normal text when printing (there's no point highlighting something that's unclickable). For this page the @print style sheet instructions look like this,

@media print {
    body { background: white; color: black; }
    h1 { border: 0; color: black; background: white; }
    #leftbar, #index { display: none; }
    #conts { width: 100%; left: 0; }
    dfn { border: 0; }
    a { text-decoration: none; color: black; }
    #conts { background: transparent; color: black }
    #conts pre { border: 0; background: transparent; }

Go on, try a print-preview!

You also might want some ouput that is generated only on the printed page, but not on the screen. For that you can use the @screen directive in the same way as @print. Alternatively you can give the item the display: none attribute in the main style-sheet, and then the display: block or inline in the @print section.


Valid XHTML 1.0!
Valid CSS2!

Copyright © 2003 Ben Edgington.