(with later amendments and comments)
This page was started quite a few years ago, to study a specific problem with HTML tables. It does not attempt to be a balanced tutorial on HTML table design in general, and the issue which it addresses is now of, at best, only specialised interest.
When HTML Tables are viewed on non-table-capable browsers, the result is usually a mess. We investigated ways of marking up tables so that they would offer some reasonable level of fallback capability when viewed on non-table-capable browsers.
The first edition of this page was started at a time when there was still a significant proportion of browsers that had absolutely no support for TABLEs. In mid-1998, this no longer seemed realistic: many of the details and reports of problems with antique browser versions were deleted at that point.
By 2003, Lynx (version 2.8.4rel.1 was reviewed) was already doing quite a decent job with tabular data, without the additional help described in this article. So, unless you need to worry about folks using older versions of Lynx (version 2.8.2rel.1 behaved in the old way), this document can now be considered of only historical interest. According to the Users Guide, this method of dealing with tables was introduced at 2.8.3, and is denoted TRST, "Tabular Representation for Simple Tables". Documentation can be found at the Lynx web site, lynx.isc.org
There are numerous situations where the "TABLE" construct is ideal for presenting information that is tabular in nature. By 1998, browsers that implement tables were widespread, and Lynx was the chief remaining issue.
The discussion has been kept sufficiently general that it should be equally applicable to tables that conform to any of the various HTML recommendations and drafts.
The first edition of the document provoked interest on the usenet group comp.infosystems.www.authoring.html and brought quite a number of emails. I gladly acknowledge the considerable input, both from these explicitly named and from too many others to list. "Abigail from Mars" sent me several emails containing excellent suggestions.
This document only covers the use of the TABLE as a means to present content that is tabular in nature. Many authors (and authoring software packages) are now using the TABLE construct rather as a layout device for many different purposes: text, images, pseudo newspaper columns etc. in ways that may or may not be capable of falling back gracefully on non-table browsers. I have deliberately avoided trying to cover such situations here: they call for a quite different approach that would confuse rather than illuminate the present issue.
Let us start from a simple table, used only for the purposes of illustration.
Deutsch British USA Haube Bonnet Hood Kofferraum Boot Trunk Benzin Petrol Gas(oline)
It can evidently be marked up thus
<TABLE> <TR><TH>Deutsch</TH><TH>British</TH><TH>USA</TH></TR> <TR><TD>Haube</TD><TD>Bonnet</TD><TD>Hood</TD></TR> <TR><TD>Kofferraum</TD><TD>Boot</TD><TD>Trunk</TD></TR> <TR><TD>Benzin</TD><TD>Petrol</TD><TD>Gas(oline)</TD></TR> </TABLE>
if we include the optional closing tags for TH, TD and TR. Here is the result on your particular browser:
However, back when some browsers did not recognise TABLE, TR, TD etc. tags at all, they ignored them, producing something like this:
DeutschBritishUSA HaubeBonnetHood KofferraumBootTrunk BenzinPetrolGas(oline)
possibly folded across several lines if a large table, (or even folded into the preceding paragraph, if you hadn't taken the precaution of closing the paragraph.)
I am assuming that your content is tabular in nature. I am also assuming that the table is small enough to fit in the browser window, and does not require multi-line entries in any of the cells.
This restriction to cell contents that each fit on one line is an over-simplification. But it will suffice for our discussion here.
Well, nowadays only very old browsers are as table-unaware as is described above. Lynx, since around version 2.5, has been somewhat table-aware, even though it doesn't actually implement the table layout. In fact, these Lynx versions will display tables pretty much as illustrated in the "Modified TABLE markup" section below, without special action by the author.
One approach that could keep your options open would be to create your source material in the form of a tab-separated data file, and then write scripts that can turn such tab-separated files into whatever kind of compromise TABLE you're currently favouring, for example one or more of the techniques below. In that way, you can leverage a single source version of each table that you produce, simply by running your latest and greatest conversion script against the original tab-separated source file.
If you make the same material available both as a table and as PRE, users can view whichever one their browser does best. Not a very exciting or innovative solution, but it's pretty much guaranteed to work. One might offer the choice from a higher-level document, so that the PREformatted document can be chosen without having to plough through the TABLE version first.
Some browsers will create a preformatted version for you, when you view a TABLE document and save-As "plain text": you can then pick out the table from the resulting plain text file and clap a PRE container around it. However, if it contains any < > or & characters, you'd want to convert those into entity representations.
Or use that conversion script idea that I mentioned before, starting from a tab-separated source file.
This technique was only useful for browsers that are completely table-unaware, so is not practically relevant nowadays. The results aren't good, but were better than nothing.
The modifications to the markup are as follows:
<BR>at the end of the last table cell contents on every row.
Note very carefully the correct location for the
BR must be inside the
table cell, as the last thing in the cell contents. In that position, it
not only produces the desired effect, it is also syntactically valid and
will pass syntax checking; placed elsewhere, it could produce bizarre
effects on some browsers, quite apart from the deleterious effect when
you try to syntax-check your documents.
Multiple white space provided on input is going to get collapsed in accordance with HTML's usual rules. The issue of stuffing with no-break spaces is discussed separately, later.
Now, making the discussed modifications to the sample table, we get:
<TR><TH><B>Deutsch </B></TH><TH><B>British </B></TH><TH><B>USA </B><BR></TH></TR>
<TR><TD>Haube </TD><TD>Bonnet </TD><TD>Hood <BR></TD></TR>
<TR><TD>Kofferraum </TD><TD>Boot </TD><TD>Trunk <BR></TD></TR>
<TR><TD>Benzin </TD><TD>Petrol </TD><TD>Gas(oline) <BR></TD></TR>
Here, I have added a space after the contents of each table cell (the one at the end of the rightmost cell, just before the BR, isn't actually necessary), as well as putting a BR tag in the place that I described.
A non-table browser is going to ignore the unknown tags, collect up the white space (and condense any multiple white space), and honour the BR tags.
Deutsch British USA|
Haube Bonnet Hood
Kofferraum Boot Trunk
Benzin Petrol Gas(oline)
The result (which will use your normal text font, whatever that might be) on the non-TABLE browsers that I have tried, such as the free versions (1.x) of WinWeb and MacWeb, pre-FM versions of Lynx, etc., will be somewhat as depicted here. Not ideal, but surely better than the unmodified result. This is also pretty much what later versions of Lynx do with an unmodified table anyway.
Ed Smith remarked that it may be useful to try interchanging the rows and columns of your table (if the size of the table allows this) to see whether the results are easier to read.
Although the closing tags
</TH>, </TD> and
are technically optional, Netscape versions have persistently
behaved in unpleasant ways when these "optional" closing tags are
omitted; and other nasty behaviour was seen in old browsers
without them; I'd definitely recommend not omitting them.
This section describes the use of deliberately invalid HTML syntax.
In spite of my misgivings over invalid HTML, I had to admit that, at the time, this technique gave remarkably effective results across a wide range of browsers. But I wouldn't recommend its use nowadays.
The technique is based on taking a pre-formatted table, and inserting table row/cell markups into it at appropriate places. Finally the whole thing is enclosed in TABLE and PRE tags, one inside the other.
Browsers that do not support tables are then expected to ignore all the table-related tags and action the PRE tags, while browsers that do support tables are expected to action the table-related tags (hopefully over-riding the effect of the PRE).
Note that HTML syntax rules are broken, since TABLE is not legal within PRE, and PRE is not legal directly inside TABLE. Although PRE is legal inside a table cell, this does not help: we need to get the entire body of the table within the scope of a single PRE.
The first version of these tests had all of the tags (
TR) fully terminated, for the reasons already given. When viewed
on Netscape, these tables were displayed below a large number of blank
lines. The explanation for this behaviour was stunningly obvious, once
it had been explained by Abigail: Netscape is treating the preformatted
newlines, outside of a table cell, in the same way that it treats
anything it finds outside of table cells - it collects up such material
separately and spits it out ahead of the actual table. The solution is
to move the preformatted linebreak inside the scope of the last cell of
the row - or to put it another way, move the terminating
</TD></TR> from the end of one line to the
beginning of the following line.
Note that, since you are dealing with pre-formatted lines, every
line-break that you put into your data will be treated as significant by
the browser, so you can't just put them where you please. What with the
table tags etc., you'll be producing some very long HTML source lines,
which you might (depending on just how you edit your source code) find
hard to handle. However there is nothing to stop you from putting line
breaks inside HTML tags, if you want to keep your input lines of
manageable length: for example you could put
</TD at the
end of one line and its final
> at the start of the next
line, and the browser would ignore the line break.
After doing browser tests on a wide range of then-available browsers, it was concluded that the best compromise was to put the TABLE inside the PRE, rather than vice versa. (The details are omitted as they are past-history now).
It's perfectly viable to use character styles such as
such composite tables. But remember that to avoid breaking even
more syntax rules, each cell of the table
must be marked up separately.
In a usenet posting I saw a question about displaying a table of Food Service hours, and wanting it to work on Lynx. The original table had a column for each day of the week, making the table uncomfortably wide for a normal 80-col terminal window on Lynx.
However, the pattern of hours for Monday-Thursday was the same, and when I had combined those columns, the result was very suitable for the "table-in-pre" approach. Well, why not take a look for yourself. If you don't have a copy of Lynx, you might try Delorie's LynxView (I've avoided offering a precomposed submission URL, out of respect for Delorie's usage notes).
I found that this displayed happily on Win Mosaic as well as on Netscape 2.0, and adapted well to different window sizes; when Opera 2.1 became available it too was tried, and did an excellent job, again adapting well to different window widths; it displayed acceptably on UdiWWW; and it displayed just fine on various Lynx versions from 2.3BETA onwards.
This method uses the HTML3.0 TAB tag to create tab stops,
<TAB INDENT=30 ID=t1> and then inserts
<TAB TO=t1> tags ahead of the
table cell contents. Most browsers disregard the HTML3.0
TAB elements and format the table undisturbed, while Lynx uses
the TABs instead.
Note that the HTML3.0 specification measured TAB positions in
ens, and Lynx interprets this by using half the
number specified on the INDENT attribute (1 em = 2 ens)
to determine the number of monospaced columns.
Lynx is in fact the major problem case by 1997 - a great pity since otherwise Lynx is an amazingly advanced browser for its purposes! The Lynx documentation states that TABs are only supported in a left-justified situation, so presumably this technique would not work in a centered table (?). Fine-tuning of positioning might be achieved with additional no-break spaces, although on the other hand those might produce effects on some table-capable browsers too.
There are two variants of a test table available for this test. This method produces bizarre results on browsers that implement both TABs and TABLEs, such as UdiWWW.
Use of this technique is problematical if you want to validate your documents against a public DTD, since TAB has not been in a W3C DTD since the HTML3.0 draft, but using the HTML3.0 DTD would preclude using a lot of the useful things that are in later DTDs such as HTML4.0. You might decide to produce a private DTD that added the TAB into an appropriate DTD (such as one of the HTML4.0 variants), with the obvious caveats about using private DTDs.
In June 1997, while looking through "Best Viewed with Any Browser", I stumbled on a reference to "Designing HTML Tables to Work with HTML 2.0 Browsers" which was (but is no longer) at the EFF, and had apparently been there since at least December 1996.
The key feature in the context of the present discussion was stuffing with no-break-space characters.
That article reports honestly that there is no guarantee of
no-break spaces being preserved, and suggests the use of some
other character (e.g dot). And, to be pedantic, that is true:
the HTML4 spec, for example, explains what to do with "white space"
characters (which it says the no-break space is not), then
explicitly excludes any specification of what to do with other
kinds of space character.
However, in practice there are few browsers that do not treat
non-break spaces like other printable characters, i.e occupying an
appropriate-size character cell each.
Consequently, it would seem that stuffing with no-break spaces as
described there gives good prospects of success.
Depending on the browser coverage you're aiming for,
it may be possible to use
or actual 8-bit characters.
Single spaces within the individual cell contents should probably be kept as ordinary spaces, so that table-capable browsers have the opportunity to flow the contents onto multiple lines when appropriate.
The technique works well with left-aligned cell contents that are padded out to a pre-determined length by adding trailing no-break spaces. It can also work reasonably well when cell contents are centered by adding no-break spaces fore and aft, but on table-capable browsers these extra spaces (typically in situations where the cell contents get flowed onto more than one line) have sometimes been observed to produce an awkward-looking layout. Nevertheless, the results seem mostly very serviceable.
Here's a version of that Food service hours table again, developed with 8-bit no-break spaces. It passes syntax validation at HTML4.0 transitional.
If you want the technique to work with old graphical browsers, then
you might want to mark up the table cells with
<TT> to get a monospaced font, otherwise it won't
line up properly; alternatively, readers may manually configure their
old browser to use a monospaced font for normal text.
Apart from that, this example worked on a good
range of browsers, from (surprisingly!) Cello through WinWeb1
to Lynx, without doing any evident harm to the table formatting
capabilities of the Big Two, Opera, arena, emacs-w3, amaya etc.
I wish I had tried this variation more seriously before!
(N.B only the 8-bit nobreak space works in some
of the older browsers, since some of them don't understand
, and some of the really old ones don't support
&#number; at all.)
Any solutions that format the page by dead-reckoning (such as the composite TABLE/PRE or the nobreak-space-stuffing methods) are liable to be thrown out of alignment if the reader is using numbered-links mode, when cells contain HTML anchor links. The TAB/TABLE method might still be able to work in that situation.
It's possible in principle to detect which browser is calling (or to be exact, to detect what the browser says it is, although this could be missing or spoofed), and send alternative versions of a document (e.g separate PRE and TABLE versions, as we considered at the start). However, this requires continuing support effort in identifying browsers and their capabilities, and it has implications for the operation of caches and cache proxy servers. I don't feel that I can really recommend it, but if you decide to after all, then I'd advise a visit to Mark Nottingham's cacheing tutorial.
The advantage is that you then have what is, from the server's point of view, a static document, that is fully eligible for caching, and needs no server-side selection or processing.
Sceptical readers will doubtless ask whether the above ideas are practical. It is, after all, a tedious job to manufacture some of the proposed solutions by hand, and might only be worth doing for a very exposed page on which a wide browser coverage is considered to be a priority. Another example would be a head or foot fragment that you're designing so that it can be included on a large number of pages.
Well yes, it depends on how you generate your HTML and what your priorities are.
I've suggested it might be worthwhile to write a script that would take, say, a tab-delimited source file for the table, and generate the desired HTML programmatically. In this way, you can have your original data in a very convenient form (say, from another data source or easily typed in by hand) that you don't need to edit, and by modifying the conversion script in the light of experience, you can generate the exact HTML that you want.
But, now (2003) that most server hits from Lynx are from version 2.8.4 or from a later/development version, it seems that all of these tricks can be consigned to history.
I can't exactly recall when I started this topic, but the structure of the first edition of this writeup was essentially complete in early 1996.
I had made occasional revisions since, including in early 1997 I removed a number of references to ancient browsers that I no longer consider relevant, and added the TAB/TABLE method.
However, in May 1998 I felt that the first edition had become too long in the tooth, so I drafted a second edition.
Minor adjustments and trimming of some obsolete material since.
Original materials © Copyright 1994 - 2006 by A.J.Flavell