Turning the Tables
30 October 2000
I’m a big fan of standards support and Cascading Style Sheets. But I find it impossible to satisfy the most doctrinaire standards advocates. I’d like to be able to use only structural markup and avoid any hint of presentational markup. I’d like to be able to have MacEdition’s pages conform to HTML 4.0 Strict instead of HTML 4.0 Transitional. But I just can’t do it. So instead, I risk the wrath of markup purists everywhere and use tables for layout.
I’d love it to be otherwise. Browsers generally wait until
they’ve received an entire table before rendering it. It’s a
good way to break your readers’ concentration by making them wait.
And it would be so nice to just use a few DIV
tags with
id
or class
attributes to define the layout.
That would be a fast site for users and one that is easily redesigned. You
want your sidebar on the right, not the left? Just edit one stylesheet!
But it’s just not feasible with current browsers. Even with IE5/Mac, CSS positioning often turns out to be What You See Is Nothing Like What You Expected. This might be why so many of the pages of markup purists have a linear, vertical structure, with little use of the horizontal dimension in their layout.
Cascading Style Sheets were an inspired, comprehensive solution to the mess
of meaning and formatting that HTML had become by the mid 1990s. You can
do so much more with CSS than
with FONT
tags and other obsolete bits of HTML: borders and
backgrounds on paragraphs, “hilighter” backgrounds when you
hover over a link; colored strips down the side of a page without needing
to use the old 2000-pixels-wide background image trick. You could even get
rid of some frames if more browsers supported the
position:fixed;
attribute.
But the CSS positioning capabilities in current browsers just aren’t up to any but the simplest layouts. And if my reading of the specs is correct, the situation won’t get much better even with full CSS2 support.
If you’re wondering how to do a sidebar in CSS, the trick is to have a
one-pixel-tall graphic that’s as wide as the sidebar you want. Set
the style on the BODY
to be
{background-image: url('yoururl/yourgif.gif'); background-repeat:
repeat-y;}
. Then put your sidebar in a DIV
with the
float:left
property and the same width as the picture. The
body text should also go in a DIV
, with the
float:right;
property. This stops it from wrapping around the
bottom of a short sidebar into the colored zone. For a right-hand sidebar,
you also need the background-position: top right;
style
defined on the BODY
tag. (Note you can’t do a
right-hand colored strip without CSS.)
In theory, you should also be able to do this just with the floated
DIV
s without the graphic. But in IE5/Mac, floated
DIV
s seem to inherit their height from the window size, not
the BODY
size. You can set the sidebar DIV
to
have height:100%
, but if your sidebar content is more than the
user’s screenful, the end disappears. If you omit the
height
style, the sidebar ends at the end of its content.
That’s ok if you want a finite sidebar pallette, but the
colored-strip look just can’t be done this way in existing browsers.
Netscape 6 PR2 at least expands the height of the sidebar
DIV
if the content is longer than a screenful. But if the
body content is all short lines, such as a list, the right-hand
DIV
will float all the way out to the right side of the
window, leaving an unsightly gap down the middle.
Sometimes, on a weekend, I’ll have another go at trying to redesign
MacEdition’s page layout using just DIVs
and CSS, even though I know I could never
implement it given the current browser population. It doesn’t work,
not even in IE5/Mac. There just doesn’t seem to be a way to say,
“I want two regions side by side. The left-hand one should be X
pixels wide. The right hand one should fill the rest of the screen. They
should be the same height, even if there isn’t enough content in one
to match the size of the other.” Even wrapping two DIV
s
inside a parent DIV
doesn’t do it: a parent
DIV
’s height is no longer determined by those of its
child elements if they have been floated. (There is a workaround
involving zero-height <br>
tags, but that’s an
unattractive kludge)
On the other hand, it’s not only browsers that have problems with non-tables-based layout, as anyone who’s ever tried to run text around a graphic in Word will know. Take heed, W3C: future versions of CSS need to learn from Word’s mistakes.
In particular, what I would like to see is the ability to specify some sort
of relationship between sibling elements. If I put two DIV
s
inside a parent DIV
, I want to be able to specify that they
should be the same height, even when I don’t know what that height
is, and even when they are floated. I want to be able to specify that two
sibling elements together fill their parent’s width. I want to be
able to specify that their widths are in particular proportions to each
other, or that one has fixed width and one fills the remainder of the
parent’s width. And I want parent DIV
s to expand to
encompass their floating children if I define them that way, not because I
did a kludgy fix. You can do this with frames in relation to the window
size, so why not elements in a given page?
Table layouts allow you to do all these things. Until these things are added to CSS, table-based layouts are here to stay.