Stylist Logo

Why [not] Use Tables?

This entry is part 11 of 15 in the series Stylist

ABSTRACT

In this entry, I’ll discuss the principal difference between block elements (as represented by <div> elements) and <table> elements, and give some guidance as to when you may decide to use one or the other in your design.

THE DIFFERENCE BETWEEN TABLE AND BLOCK-LEVEL ELEMENTS

I’ll start by displaying the biggest difference between the two elements:

Supercalifragilisticexpialidocious
Supercalifragilisticexpialidocious

The top section (cyan-colored) is defined by a <div> element, and the bottom section (yellow) is defined by a <table>. They are each set to be 40 pixels high, and 100 pixels wide. Here is the code:

Example 1

<div style="height:40px;width:100px;font-size:large;line-height:40px;vertical-align:middle;background-color:cyan">
	Supercalifragilisticexpialidocious
</div>

<table cellpadding="0" cellspacing="0" style="margin-top:20px;line-height:40px;font-size:large;background-color:yellow; width:100px">
	<tr>
		<td style="height:40px;vertical-align:middle">Supercalifragilisticexpialidocious</td>
	</tr>
</table>

Notice that they are both set to display exactly the same size, yet only the <div> element actually stuck to the letter of the law. It stayed exactly 100 pixels wide, and allowed the content to overflow. The <table> element basically ignored the “width” property value, and stretched out to completely contain the content text.

Most text content will break, and will fit within a restricted <div>. The big word we use here is an exception. Most words aren’t that long. However, images often are big, and they can overflow block element bounds as well.

Here is an example with the word broken up a bit:

Super califragilistic expialidocious
Super califragilistic expialidocious

Wow. What happened there? Well, exactly the same thing as before. The content overflowed the bounds of the containing <div> element, only, this time, it went down, as well as out. In fact, it is all mixed up with the text being displayed by the <table> element, which dutifully stretched to accommodate the oversize content. These lines are so far apart because I gave them a big line-height property value.

Here is the code:

Example 2

<div style="height:40px;width:100px;font-size:large;line-height:40px;vertical-align:middle;background-color:cyan;color:green">
	Super califragilistic expialidocious
</div>

<table cellpadding="0" cellspacing="0" style="margin-top:20px;line-height:40px;font-size:large;background-color:yellow;width:100px">
	<tr>
		<td style="height:40px;vertical-align:middle">Super califragilistic expialidocious</td>
	</tr>
</table>

We could remove the vertical overflow by removing the height property from the <div> style. The div will stretch vertically in a similar manner to a table. The width will not do this (it must be specified, or it will default to 100%):

Super califragilistic expialidocious
Super califragilistic expialidocious

Here is the code for that example (Note that only a width is specified):

Example 3

<div style="width:100px;font-size:large;line-height:40px;vertical-align:middle;background-color:cyan;color:green">
	Super califragilistic expialidocious
</div>

<table cellpadding="0" cellspacing="0" style="margin-top:20px;line-height:40px;font-size:large;background-color:yellow;width:100px">
	<tr>
		<td style="height:40px;vertical-align:middle">Super califragilistic expialidocious</td>
	</tr>
</table>

Now, you can make a <div> element clip or scroll to accommodate oversize content. You do this by assigning an overflow property to the <div> element, like so:

Supercalifragilisticexpialidocious
Supercalifragilisticexpialidocious
Supercalifragilisticexpialidocious

The above example shows the three other states of the overflow property. The top one is overflow:hidden, in which the overflow is clipped, the second one shows overflow:scroll, in which scrollbars are displayed all the time, but are only activated if the content is too large to display. In that case, it is clipped, but you can scroll to see it. The last one is overflow:auto, in which a scrollbar is displayed as necessary.

In order to see how the overflow:scroll and overflow:auto works, make the window very small (in the example linked below; not this window), and you’ll see the scrollbars activate.

The code is here:

Example 4

<div style="margin-top:8px;height:40px;width:100px;font-size:large;line-height:40px;vertical-align:middle;background-color:cyan;overflow:hidden">
	Supercalifragilisticexpialidocious
</div>

<div style="margin-top:8px;height:40px;width:100%;font-size:large;line-height:40px;vertical-align:middle;background-color:cyan;overflow:scroll">
	Supercalifragilisticexpialidocious
</div>

<div style="margin-top:8px;height:40px;width:100%;font-size:large;line-height:40px;vertical-align:middle;background-color:cyan;overflow:auto">
	Supercalifragilisticexpialidocious
</div>

So, from this, you can see that a <table> can be useful if you can’t control the content, and need a container that stretches to fit the content. Tables are robust as hell. They can be bent, folded, spindled and mutilated with ease. However, this very behavior can break many controlled layouts, and can make the page load problematic, especially for pages with a lot of content. It can be difficult to make large changes to the appearance of the page if it uses a lot of table-based layout.

Also, the markup for table-based layout can be rather complex (but the CSS for block-element layout can be much more complex, so the “complexity” argument doesn’t actually hold much water).

<div> element-based layouts are far better for controlling the layout of the page, as they react to the context, not the content. For example, the reason that shrinking the window doesn’t work for making the overflows work on this page is because the container for this page is a fixed width. All that text that spills out to the right (like the code listings) is actually overflowing the right edge. Since the container is fixed, making the window smaller doesn’t change it, so the contained <div> elements don’t change either.

Myself, I recommend against using tables for layout. I do use them occasionally, but rather sparingly. Often, you don’t have any choice, as many content management systems use tables a lot.

However, don’t listen to all that crazy talk about the evils of tables, and how rotten a designer you are if you use them. If you really need to use them, go ahead, but you’ll be better off learning to do without them.

I’ll show you one more reason that I will use table layouts, then we’ll go on to positioned block-level elements.