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 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!
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.
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); </style>
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.
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.