Slowly, and not without growing pains, web professionals are transitioning from old-school HTML table layouts to Cascading Style Sheets (CSS) backed by streamlined, structural XHTML markup. Successfully making the transition requires a change in thinking. As designers, we're trained to see web pages as pure visual layouts like print you can click. But a standards-conscious designer won't even think about how a page looks until she has first figured out its underlying structure. That may seem an odd way to approach design, but it provides three benefits:
1. Sites conceived this way almost always save bandwidth. Pages load faster, and users are more likely to keep clicking through.
2. When the underlying structure is sound, and when CSS delivers your layout, your site may work as well in a Palm Pilot, screen reader, or web-enabled phone as it does in traditional browsers.
3. Sites that are structured before they are 'designed' are much easier to redesign.
In this article I'll share tips that can help you shave bandwidth and save hours (or even weeks) of redesign drudgery.
Structure Your Content for Reusability
Consider the macromedia.com layout shown here.
To a traditional web designer, this is an HTML table consisting of two rows and two columns. The first row, containing the page title and breadcrumb trail, spans both columns. The second row contains a wide content column and a narrower navigation column. (The content column might contain additional, nested tables used to control the positioning of images relative to their descriptive texts, but let's not quibble.)
Such a table layout will work in any graphical browser later than Netscape 1.1, but it eats user bandwidth and it cannot be repurposed. When it's time to redesign, you will have to start from scratch.
A web designer who has dabbled in CSS might approach the same layout problem by creating absolutely positioned divs (divisions), with names like 'top_box,' 'left_box,' and 'right_box.' This technique would work in any recent browser and would waste less bandwidth than the HTML table approach. But it limits redesign options because the labels refer to positions on the page instead of the purpose each div serves.
There is a third way. A standards-oriented designer would analyze the function each div performs and assign an appropriate generically structural label, such as 'title_area,' 'main_content,' and 'sidebar' (or 'nav').
Why is this any better than 'top_box,' 'left_box,' and 'right_box'?
It's better because structural labels do not leave you stuck with last year's visual placement or layout idea. A 'sidebar' can be placed on the left or right, at the top or bottom, or (if you're feeling saucy) in the middle of the page. Even more flexibly, a 'nav' can be horizontal or vertical. It can be styled to look like a list, like breadcrumbs, or like a series of clickable buttons. By contrast, a 'right box' is always a right box; you're unlikely to move it or rethink it.
Technically, of course, the names don't matter. In a redesign, you could stick 'right_box' on the left and slide 'left_box' over to the right. But you'd have a tough time keeping track of it all, and so would any client or colleague who inherited your design after you moved on to another project or job. When I started designing with CSS, I thought it was cool that I could label my divs 'smells' 'like,' 'teen,' and 'spirit.' And it was cool until my client requested a redesign and I couldn't remember what my labels meant.
As a bonus, structural labeling can enhance usability by curbing the tendency to add elements to a layout, not because they perform a function, but because you just learned a new trick in Fireworks or Photoshop.
Use Page Structure to Write Leaner Style Sheets
Now that you've got those clean structural labels, use them to create smarter CSS and tighter, less wasteful markup.
Suppose the site I'm designing sports a sidebar, and I want text in that sidebar to be 11 pixels tall. Style sheet neophytes might create a special class:
.eleven{
font-size: 11px;
}
They would then write XHTML that uses that class over and over again:
<div id="sidebar">
<p class="eleven">The text in this paragraph is 11px tall.</p>
<p class="eleven">This text is also 11px tall.</p>
<p class="eleven">So is the text in this paragraph.</p>
</div>
It works, but it's a waste of user and server bandwidth like eating peas with tweezers, one pea at a time.
Fortunately, CSS lets me save bandwidth by using one layout element to select another. In CSS1 these are called contextual selectors because their value varies by context; in CSS2 (a later, more sophisticated version of the CSS spec) they are called descendant selectors because they are the offspring of particular branches in the document tree. No matter what you call them, they spare you and your users from the nuisance of unnecessary classes. I can use them to create a rule that will apply only to paragraphs that occur in the sidebar:
#sidebar p{
font-size: 11px;
}
I can then write uncluttered markup like this:
<div id="sidebar">
<p>The text in this paragraph is 11px tall.</p>
<p>This text is also 11px tall.</p>
<p>So is the text in this paragraph.</p>
</div>
Each paragraph is just a paragraph; no extra class attribute is required. Paragraphs within the sidebar will obey this CSS rule; those elsewhere on the page won't be affected by it.
Look, Ma, No Spacer GIFs!
You can use descendant selectors to wrap a black border around any image that appears in the sidebar (saving production time), and to surround that image with a precise amount of vertical white space without using spacer GIF images or nested tables:
img{
display: block;
border: 0;
}
#sidebar img {
margin: 15px 0;
border: 1px solid #000;
}
The first rule turns off borders on all images and sets them to display: block, which means they will automatically be followed by a carriage return there's no need to follow each image with a <br/> tag or to wrap it in a div. The second rule says that some images, namely those used in the sidebar, will have a one-pixel black border and vertical white space of exactly 15 pixels.
To achieve those same effects, designers who don't know about descendant selectors might waste bandwidth on markup like this:
<div id="sidebar">
<div style="margin-top: 5px; margin-bottom: 5px;">
<img class="blackborder" alt="John Smith" height="150" width="200" src="johnsmith.jpg" />
</div>
</div>
But with descendant selectors, tighter, cleaner markup is guaranteed:
<div id="sidebar">
<img alt="John Smith" height="150" width="200" src="johnsmith.jpg" />
</div>
And because the style sheet stays cached in the user's browser, the same effects can be repeated on a thousand pages without wasting bandwidth on excess classes and without forcing designers to craft redundant templates. Rethinking basic design practices is not easy old habits die hard but it pays off in improved user experience, reduced hosting and bandwidth costs, and fewer hours of production tedium. Try it; you'll like it.
Jeffrey Zeldman (www.zeldman.com) is the author of the best-selling Designing With Web Standards (www.zeldman.com/dwws/), founder of Happy Cog Studios (http://www.happycog.com/) and publisher of A List Apart Magazine (http://www.alistapart.com/)for people who make websites.