Zap Common Browser Bugs

The last time I went on a picnic, I meticulously ant-proofed everything. But it didn't matter: those little buggers showed up everywhere. The same thing can happen to flawlessly written HTML code–even if you're sure your code is perfect, a browser can wreak havoc with your carefully created design.

There are all kinds of ways that bugs can creep into your Web pages. The small font that looks so clean on a PC may look tiny on a Mac. The spacer rows you added between a page's sections may disappear in Netscape Navigator. Or the precisely proportioned headlines and subheadlines on a page (such as ‹font size=4›, ‹font size=3›, or ‹font size=2› ) might look different on different machines.

It's easy to assume that the cause lies in your HTML-writing skills–after all, who hasn't made a glaring mistake in their code at least once? But sometimes it's the browser's fault. Browsers process and read HTML differently, and that can affect the way your page renders. In addition, users may have adjusted their browsers' font settings–some people prefer to read everything in 16-point Courier–and that can throw your designs out-of-whack.

Web developers face the challenge of building pages that anyone, using any browser on any platform, can read. So how can you do that without driving yourself buggy? It's easy–remember what the biggest rendering bugs are and work around them. This article identifies some of the most common problems and shows how to write HTML around them. (I've included lines of HTML to illustrate my points, but if you want to see the complete code, go to "Complete Code".)


Problem: Inconsistent Fonts

Users muck around with their browsers' font settings for a couple of reasons: legions of Web developers have fallen in love with small fonts, and Microsoft Internet Explorer has added the Larger and Smaller font buttons to the browser tool bar. As a result, plenty of Web visitors are undoing designers' itty-bitty font specifications by clicking on the Larger button until they can read the text. This can throw a layout horribly out of proportion, with bloated line spaces and badly broken subheadlines.


Solution: Use Flexible HTML Tags

The only way you can absolutely guarantee consistent text appearance in your visitors' browsers is to turn each page into one big GIF file–highly impractical. A more realistic solution is to prevent font mishaps by simplifying your HTML. If you want small text, use the ‹small› tag. A browser will then scale the text relative to a user's default font. For instance, if the default font is 12-point, the small font will be 10-point.

If you want to incorporate a variety of font sizes in a page, use the ‹big› and ‹small› tags as HTML headings. These varying sizes scale proportionally to the visitor's default browser settings, guaranteeing preservation of the general proportions of a layout no matter how large or small a visitor's font settings. Tags such as ‹font size="+2"› and ‹font size="-1"› don't scale nearly so elegantly.


Problem: Migrating Layout

In theory, the first element of a Web page–whether it's a table, a graphic, or something else–should use the upper-left corner of a browser window as the point of origin. That's true, but it's not exact. Browsers add space that makes your layout migrate several pixels away from the corner (see "Drifting Layout"). If it's important that your layout start in the corner, without any spaces above or to the left, this browser offset could throw your whole design off.

Drifting Layout To prevent browsers from shifting your layout several pixels down and over (right), add margin attributes ( marginwidth, marginheight, leftmargin, topmargin ) to your HTML code.


The amount of extra space a browser adds to your layout depends on the user's platform: on the Mac, whether you're viewing a page with Navigator or Internet Explorer, the layout will move 8 pixels down and 8 pixels to the right. PC users have it even worse: the offset in Internet Explorer for the PC is 10 pixels down and 15 to the right.


Solution: Add Margin Attributes

Browser offset is one of the easier design problems to work around–just add margin attributes to your ‹body› tag. You will need four of them.

marginwidth determines how many pixels of space are between the left edge of a browser window and the items within an HTML document's body.

marginheight sets the placement of items relative to the top of the browser.

leftmargin tells the browser the pixel width of the left margin (similar to the marginwidth attribute).

topmargin tells the browser the pixel width of the top margin (similar to the marginheight attribute).

Even though there seems to be duplication in the attribute tags, you need all four because Internet Explorer 3.0 supports the marginwidth and marginheight tags while the 4.0 browsers support the leftmargin and topmargin tags. Unfortunately, if your users access your site with Navigator 3.0, you're out of luck–there's no way to get rid of offset with that browser.


Problem: Shrinking Table Cells

HTML tables were designed to let Web developers format tabular data neatly; you aren't really supposed to use tables to control page layout. But that doesn't mean we can't complain about the misbehavior of our misused tables.

One of the most common complaints about tables is that table cells don't maintain their sizes. (This tends to affect Navigator viewers more often than their Internet Explorer counterparts.) When you write a table, you should set both the width of the table and the widths of its constituent cells; this helps the table render quickly, because the browser knows how wide every cell must be. Otherwise, it has to read the table contents and try to scale the cells proportionally.

But Navigator may still run into some problems with your tables, sometimes even shrinking cells. When a cell's content isn't as wide as the cell itself, the browser snaps the cell to the width of the content.


Solution 1: Make Cell Content the Right Size

One way to make sure a cell doesn't shrink is to fill it with content that will force a cell to maintain its size, as in the sample cells following.

Sample 1: ‹td width="20"›    ‹/td›

Sample 2: ‹td width="400"›‹img src='banner.gif' width="400"›‹/td›

The first sample shows how to use nonbreaking spaces ( &nbsp ), which are handy if you're using a cell for space or for a margin. The second sample contains a graphic that's the same width as the cell.


Solution 2: Make Your Layout Flexible

The second way to step around the shrinking-cell problem is to modify your layout so that precise cell size doesn't matter. See "The Flexible Layout" for an example of a table that can expand and contract as needed.


Problem: Misaligned Cell Content

Another common complaint about tables is that the contents of a cell don't align as intended. For instance, you may want the contents of two cells to adjoin, but you end up with white space between cells.


Solution 1: Don't Settle for Default Table Attributes

Browsers default to the following attributes: table cellpadding 1 pixel, table cellspacing 1 pixel, valign=top, and align=left. These defaults can mess up a table's appearance, so it's up to you to specify the right values for your layout. See "Malignant Alignment" for an example of how to adjust attributes.


Solution 2: Compact Your Code

After you've tweaked your table attributes, the end result may work beautifully in Internet Explorer but still go awry in Navigator–because Navigator inserts extra white space at line breaks and hard returns.

You can eliminate this white space by compacting your code: eliminating extra line breaks, hard returns, and tabs. Compacting doesn't affect the format of text within ‹body› tags or ‹table› tags–it just cleans up the spaces between individual tags. Here's what compacted code looks like:

‹! doctype html public "-//w3c//dtd
html 4.0 transitional//en" "http://
www.w3.org/tr/rec-html40/loose.dtd"›
‹html›‹head›‹title›table test #2
‹/title›‹/head›‹body bgcolor=
"#FFFFFF" marginheight="0"
marginwidth="0" leftmargin="0"
topmargin="0"›‹table width="360"
cellspacing="0" cellpadding="0"
border="0"›‹tr valign="bottom"›
‹!--put table content here--›
‹/tr›‹/table›‹/body›‹/html›

It's harder for people to read but much better for browsers. Tip: If you're using Bare Bones Software's BBEdit, you can use the Format Text option (under the Utilities menu) to compact code; otherwise, you'll have to wipe out white space on your own.


The Secret to Bug-Free Pages

The real secret to writing bug-free pages is simple: avoid building complicated pages. Using HTML as a design language to control the visual attributes of a page is a tricky proposition at best, and the more tricks you use, the more likely you are to encounter a bug.

This isn't meant to discourage you from pushing design limits with HTML. If you're truly committed to executing cutting-edge design online, however, you might want to consider using Macromedia Flash or some other technology that gives you a great deal of control over the visual appearance of your Web pages.

On the other hand, there's a certain Zen appeal in writing simple HTML: you can concentrate on making your pages look attractive and original–and rest assured that they'll look consistent across different browsers.

Online Senior Editor LISA SCHMEISER prefers alfresco coding. She's the author of The Web Design Templates Sourcebook (New Riders, 1997) and The Complete Website Upgrade & Maintenance Guide (New Riders, 1998).

April 2000 page: 106

Complete Code Browser Offset Code

The HTML document I used to show the browser offset above was written like this:

<! doctype html public "-//w3c//dtd html 4.0 transitional//en"
"http://www.w3.org/tr/rec-html40/loose.dtd">
<html>
<head>
<title>Browser offset test #1</title>
</head>

<body bgcolor="#003366">
<table width="600" cellpadding="0" cellspacing="0" border="0"
bgcolor="#FFFFFF">
<tr valign="top">
<td width="600">
  
</td>
</tr>
</table>

</body>
</html>

Now, the new and non-offset version looks like this:

<! doctype html public "-//w3c//dtd html 4.0 transitional//en"
"http://www.w3.org/tr/rec-html40/loose.dtd">
<html>
<head>
<title>Browser offset test #1</title>
</head>

<body bgcolor="#003366" marginheight="0" marginwidth="0"
leftmargin="0" topmargin="0">
<table width="600" cellpadding="0" cellspacing="0" border="0" bgcolor="#FFFFFF">
<tr valign="top">
<td width="600">
  
</td>
</tr>
</table>

</body>
</html>

Checking Your Table Attributes

Here's the before table:

<! doctype html public "-//w3c//dtd html 4.0 transitional//en"
"http://www.w3.org/tr/rec-html40/loose.dtd">
<html>
<head>
<title>table test test #1</title>
</head>

<body bgcolor="#FFFFFF" marginheight="0" marginwidth="0"
leftmargin="0" topmargin="0">
<table width="400" cellspacing="4" cellpadding="4" border="1">
<tr>
<td width="200" valign="top" align="left"><IMG SRC="images/block1.gif"
ALT="block1" WIDTH="180" HEIGHT="180" BORDER="0"></td>
<td width="200" valign="top" align="left"><IMG SRC="images/block3.gif"
ALT="block3" WIDTH="180" HEIGHT="180" BORDER="0"></td>
</tr>
<tr>
<td width="200" valign="top" align="left"><IMG SRC="images/block4.gif"
ALT="block4" WIDTH="180" HEIGHT="180" BORDER="0"></td>
<td width="200" valign="top" align="left"><IMG SRC="images/block2.gif"
ALT="block 2" WIDTH="180" HEIGHT="180" BORDER="0"></td>
</tr>
</table>
</body>
</html>

Here's the after table:

<! doctype html public "-//w3c//dtd html 4.0 transitional//en"
"http://www.w3.org/tr/rec-html40/loose.dtd">
<html>
<head>
<title>table test test #2</title>
</head>

<body bgcolor="#FFFFFF" marginheight="0"
marginwidth="0" leftmargin="0" topmargin="0">
<table width="360" cellspacing="0"
cellpadding="0" border="0">
<tr valign="bottom">
<td width="180" align="right"><IMG
SRC="images/block1.gif" ALT="block1"
WIDTH="180" HEIGHT="180" BORDER="0"></td>
<td width="180" align="left"><IMG
SRC="images/block3.gif" ALT="block3"
WIDTH="180" HEIGHT="180" BORDER="0"></td>
</tr>
<tr valign="top">
<td width="180" align="right"><IMG
SRC="images/block4.gif" ALT="block4"
WIDTH="180" HEIGHT="180" BORDER="0"></td>
<td width="180" align="left"><IMG
SRC="images/block2.gif" ALT="block 2"
WIDTH="180" HEIGHT="180" BORDER="0"></td>
</tr>
</table>
</body>
</html>
Malignant Alignment

To take out unwanted space between cell content, follow these steps (for the complete before-and-after HTML, see "Complete Code"):

Before

After

  Change the table width to reflect the table's contents.

  Move the valign attribute to the table row, since it's consistent for each cell, and set images in the top row to align vertically with the bottom of the row:

‹table width="360" cellspacing="0"
    cellpadding="0" border="0"›
‹tr valign="bottom"› ‹/tr›
‹tr valign="top"› ‹/tr›‹/table›

  Align the cells by pushing them to the right if they're on the left-hand side, and to the left if they're on the right-hand side.

The Flexible Layout

Making sure that visitors to your site see the exact design you intended can be tricky. Sometimes creating a design that can change depending on who's visiting your site is easier. In the case of tables, one option is to make a row of cells that can shrink.

In this example, I wanted to have a table with white space on the left-hand side, so I formatted the left-hand column like this: ‹td width="20"› ‹/td›. By writing the code like this, I built in flexibility: the column will either be 20 pixels wide or shrink to the size of its contents–one nonbreaking space ( &nbsp ). The size of the nonbreaking space depends on the font-size settings on the user's browser.

Outsmart the Browser Even a browser that shrinks the left column in this table wont ruin the layout. To make sure the column doesnt disappear, though, you need to insert a nonbreaking space.


Browsers that read and set cell sizes based on their specific width will set the column width to 20 pixels; browsers that render cell sizes based on the width of the cell content alone will shrink the column to the size of the nonbreaking space. Since the purpose of the column is to provide a buffer of white space on the left-hand side of the page, the page renders acceptably on any browser.

Subscribe to the Best of Macworld Newsletter

Comments