Tables and Layouts

Tables are the most reliable way of laying out text and graphics in HTML; they also require meticulous attention to get right, and have their limits.

Basically, a table is a simple grid of rows and columns, each "cell" of which can contain data. A simple table would look like this:

Cell 1 Data Cell 2 Data

The code for this table looks like this:

<table width="80%">  
<tr>  
<td">Cell 1 Data  
</td>  
<td">Cell 2 Data  
</td>  
</tr>  
</table>

Now, this might be hard to see as such, so I'll add some borders using a style sheet, so you can see what's happening:

Cell 1 Data Cell 2 Data

How this code works:

<table width="80%"> — table establishes that everything until the table is closed with /table is part of the table; width, in this case, sets the width of the table to be 80 per cent of the total browser window width.

<tr> — tr establishes a table row, measuring the whole width of the table.

<td> — td establishes table data, or a "cell" in the row. Once the table data has been opened, any content, whether text or image, can be placed inside (you can even "nest" a second table within the td of a larger table, but this can be extremely difficult to manage.

</td> — /td is needed to close the table data cell.

<td> — Now another cell can be opened.

</td> — /td closes the second table data cell.

</tr> — /tr closes the table row.

</table> — /table closes the whole table.

More Elaborate tables

A slightly more elaborate table might look like this:

This is the table Caption
Column 1 Header Column 2 Header
Cell 1 Data Cell 2 Data
Cell 3 Data Cell 4 Data

or like this:

Cell 1 Data Cell 2 Data Cell 3 Data
Cell 4 Data Cell 5 Data spread out over 2 cells by use of <colspan="2"> in the <td> tag
Cell 6 Data Cell 7 Data Cell 8 Data

or like this:

Cell 1 Data Cell 2 Data
Cell 3 Data Cell 4 Data

The above table uses some color, as well as two tags within the <table> tag: cellpadding and cellspacing. Cellspacing tells the table to make the spaces between cells a certain pixel width. For example, here's the same table with Cellspacing set to 2:

Cell 1 Data Cell 2 Data
Cell 3 Data Cell 4 Data

And here's the cellspacing set to 12, just to exaggerate the difference:

Cell 1 Data Cell 2 Data
Cell 3 Data Cell 4 Data

Here's the first table again, this time with cellpadding set to 2:

Cell 1 Data Cell 2 Data
Cell 3 Data Cell 4 Data

And now with cellpadding set to 20:

Cell 1 Data Cell 2 Data
Cell 3 Data Cell 4 Data

Between cellpadding and cellspacing, you can format a table quite nicely, making each of the individual cells clearly legible and distinct from the others.

Relative vs Absolute Measurement

You'll note, if you drag the browser window larger and smaller, that the table automatically resizes itself. This is because you, as the designer, don't really know how big your audience's monitor is: generally 640 x 480 pixels is considered the smallest acceptable, but it could be much larger. Making your tables dynamically resize themselves can be a good way of using that space. On the other hand, if you're trying to precisely align graphics within a table, you might need absolute control over the table's dimensions. Fortunately, you have this control if you want it. In the first table below, the table dimensions are indicated proportionally, as have the above examples:

30% Width 70% Width

In this table, however, absolute pixels are specified, so that the table will not resize itself to the browser window. If the window is smaller than the width indicated, though, the table will bleed off the right side of the screen:

150 pixel width 350 pixel width

This can be risky, because on a monitor with less resolution than the table calls for, the display can be quite annoying. So while it's okay to use an absolute table layout like this, it should be used with caution.

Images in tables

Tables can also include images, like so:

This doesn't look right, so I'll just take out that border style:

Still looks funny. That's because some browsers will, if no values are explicitly set, default cellpadding and cellspacing values, and probably values that you don't want. So to fix this, set all the values to zero:

Now our image is seamless. This could be useful if, say, you wanted to attach a different link to each part of the image:

Here's a fairly complex table:

               
     

Headline

     
        Links:
The other headline
The next headline
Yet another headline
Still another headline
More headlines
Even more headlines
Headlines!!
Lots of headlines!
Links for sale!
 
         
               
  You'll note, if you drag the browser window larger and smaller, that the table automatically resizes itself. This is because you, as the designer, don't really know how big your audience's monitor is: generally 640 x 480 pixels is considered the smallest acceptable, but it could be much larger. Making your tables dynamically resize themselves can be a good way of using that space. On the other hand, if you're trying to precisely align graphics within a table, you might need absolute control over the table's dimensions.    

If the border is hidden, the table becomes an invisible layout tool:

     

Headline

     
        Links:
The other headline
The next headline
Yet another headline
Still another headline
More headlines
Even more headlines
Headlines!!
Lots of headlines!
Links for sale!
 
         
               
  You'll note, if you drag the browser window larger and smaller, that the table automatically resizes itself. This is because you, as the designer, don't really know how big your audience's monitor is: generally 640 x 480 pixels is considered the smallest acceptable, but it could be much larger. Making your tables dynamically resize themselves can be a good way of using that space. On the other hand, if you're trying to precisely align graphics within a table, you might need absolute control over the table's dimensions.    

Here's a table missing the closing </table> tag:

In some browsers, the table won't display at all; others are more forgiving. This is the big weakness of tables: one misplaced tag, and the whole structure falls apart. However, if you lay out your table in a readable fashion, figuring out what's missing shouldn't take too long.

Tables and Style Sheets

Tables become even more useful when combined with CSS, or Cascading Style Sheets. You can use the table to provide structure, then use styles to define what the table should look like. Let's take this example:

table layout

By drawing some lines on this layout, we can make the structure more visible, which will help us make a simple table to place things exactly:

table layout

Let's start by creating a really simple table to get the structure down; we can see that this layout has two tiers and four columns, so we'll make that first:

Logo Navigation Name [Blank]
Icons [Blank] Image Text
<table border="1" width="640">
	<tr>
		<td>Logo</td>
		<td>Navigation</td>
		<td>Name</td>
		<td>[Blank]</td>
	</tr>
	<tr>
		<td>Icons</td>
		<td>[Blank]</td>
		<td>Image</td>
		<td>Text</td>
	</tr>
</table>

Notice that I'm not concerned about appearance just yet, just the structure.

Now we can add a little colour, to make the layout more closely resemble the intended appearance. We can do this by applying styles to the table elements:

Logo Navigation Name [Blank]
Icons [Blank] Image Text
<table border="1" width="640" style="background-color:rgb(130,147,138)">
	<tr>
		<td style="background-color:rgb(240,234,162)">Logo</td>
		<td>Navigation</td>
		<td>Name</td>
		<td>[Blank]</td>
	</tr>
	<tr>
		<td style="background-color:rgb(240,234,162)">Icons</td>
		<td>[Blank]</td>
		<td>Image</td>
		<td>Text</td>
	</tr>
</table>

Next, we can add some width specifications to the columns, to match the measurements on the layout image:

Logo Navigation Name [Blank]
Icons [Blank] Image Text
<table border="1" width="640" style="background-color:rgb(130,147,138)">
	<tr>
		<td style="background-color:rgb(240,234,162);width:228px;height:140px">
			Logo</td>
		<td style="width:120px">Navigation</td>
		<td style="width:260px">Name</td>
		<td>[Blank]</td>
	</tr>
	<tr>
		<td style="background-color:rgb(240,234,162)">Icons</td>
		<td>[Blank]</td>
		<td>Image</td>
		<td>Text</td>
	</tr>
</table>

Now I'll add some images in their respective table cells:

Logo Navigation Name [Blank]
[Blank] Image Text
<table border="1" width="640" style="background-color:rgb(130,147,138)">
	<tr>
		<td style="background-color:rgb(240,234,162);width:228px;height:140px">
			Logo</td>
		<td style="width:120px">Navigation</td>
		<td style="width:260px">Name</td>
		<td>[Blank]</td>
	</tr>
	<tr>
		<td style="background-color:rgb(240,234,162)">
		<img src="http://www.winsorgallery.com/images/2/baldwin_1.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/borden_4.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/bos_8.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/cho_10.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/clemens_1.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/dittmar_1.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/gammell_1.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/gleave_3.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/johnston_1.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/seok-lim_1.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/liu_1.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/ostoich_3.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/park-spurr_3.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/plewman_1.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/saito_1.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/son_1.jpg" alt="" />
		</td>
		<td>[Blank]</td>
		<td>Image</td>
		<td>Text</td>
	</tr>
</table>

Now these images look a little crammed; in the original layout they had a bit of space around them, so we should add some padding. An awkward way to do this would be as such:

<table border="1" width="640" style="background-color:rgb(130,147,138)">
	<tr>
		<td style="background-color:rgb(240,234,162);width:228px;height:140px">
			Logo</td>
		<td style="width:120px">Navigation</td>
		<td style="width:260px">Name</td>
		<td>[Blank]</td>
	</tr>
	<tr>
		<td style="background-color:rgb(240,234,162)">
		<img style="padding-left:18px;padding-bottom:24px" 
		src="http://www.winsorgallery.com/images/2/baldwin_1.jpg" alt="" />
		<img style="padding-left:18px;padding-bottom:24px" 
		src="http://www.winsorgallery.com/images/2/borden_4.jpg" alt="" />
		<img style="padding-left:18px;padding-bottom:24px" 
		src="http://www.winsorgallery.com/images/2/bos_8.jpg" alt="" />
		<img style="padding-left:18px;padding-bottom:24px" 
		src="http://www.winsorgallery.com/images/2/cho_10.jpg" alt="" />
		<img style="padding-left:18px;padding-bottom:24px" 
		src="http://www.winsorgallery.com/images/2/clemens_1.jpg" alt="" />
		<img style="padding-left:18px;padding-bottom:24px" 
		src="http://www.winsorgallery.com/images/2/dittmar_1.jpg" alt="" />
		<img style="padding-left:18px;padding-bottom:24px" 
		src="http://www.winsorgallery.com/images/2/gammell_1.jpg" alt="" />
		<img style="padding-left:18px;padding-bottom:24px" 
		src="http://www.winsorgallery.com/images/2/gleave_3.jpg" alt="" />
		<img style="padding-left:18px;padding-bottom:24px" 
		src="http://www.winsorgallery.com/images/2/johnston_1.jpg" alt="" />
		<img style="padding-left:18px;padding-bottom:24px" 
		src="http://www.winsorgallery.com/images/2/seok-lim_1.jpg" alt="" />
		<img style="padding-left:18px;padding-bottom:24px" 
		src="http://www.winsorgallery.com/images/2/liu_1.jpg" alt="" />
		<img style="padding-left:18px;padding-bottom:24px" 
		src="http://www.winsorgallery.com/images/2/ostoich_3.jpg" alt="" />
		<img style="padding-left:18px;padding-bottom:24px" 
		src="http://www.winsorgallery.com/images/2/park-spurr_3.jpg" alt="" />
		<img style="padding-left:18px;padding-bottom:24px" 
		src="http://www.winsorgallery.com/images/2/plewman_1.jpg" alt="" />
		<img style="padding-left:18px;padding-bottom:24px" 
		src="http://www.winsorgallery.com/images/2/saito_1.jpg" alt="" />
		<img style="padding-left:18px;padding-bottom:24px" 
		src="http://www.winsorgallery.com/images/2/son_1.jpg" alt="" />
		</td>
		<td>[Blank]</td>
		<td>Image</td>
		<td>Text</td>
	</tr>
</table>

This does work, though:

Logo Navigation Name [Blank]
[Blank] Image Text

A more elegant and flexible way to do this, though, would be to add a class to the table cell, then define some parameters for that class to space out all the images. The class would be declared in the styles for the page, like this:

<style type="text/css">
.icons img {padding-left:18px;padding-bottom:24px}
</style>

<table border="1" width="640" style="background-color:rgb(130,147,138)">
	<tr>
		<td style="background-color:rgb(240,234,162);width:228px;height:140px">
			Logo</td>
		<td style="width:120px">Navigation</td>
		<td style="width:260px">Name</td>
		<td>[Blank]</td>
	</tr>
	<tr>
		<td style="background-color:rgb(240,234,162)" class="icons">
		<img src="http://www.winsorgallery.com/images/2/baldwin_1.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/borden_4.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/bos_8.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/cho_10.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/clemens_1.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/dittmar_1.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/gammell_1.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/gleave_3.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/johnston_1.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/seok-lim_1.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/liu_1.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/ostoich_3.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/park-spurr_3.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/plewman_1.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/saito_1.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/son_1.jpg" alt="" />
		</td>
		<td>[Blank]</td>
		<td>Image</td>
		<td>Text</td>
	</tr>
</table>
Logo Navigation Name [Blank]
[Blank] Image Text

Same effect, but less code, and more centralized statements.

In fact, by "classifying" each table cell, we can determine what its contents should look like. Let's add some navigational links to the table:

Logo ArtistsExhibitsPressAbout Us Name [Blank]
[Blank] Image Text
<table border="1" width="640" style="background-color:rgb(130,147,138)">
	<tr>
		<td style="background-color:rgb(240,234,162);width:228px;height:140px">
			Logo</td>
		<td style="width:120px"><a href="#">Artists</a>
		<a href="#">Exhibits</a>
		<a href="#">Press</a>
		<a href="#">About Us</a></td>
		<td style="width:260px">Name</td>
		<td>[Blank]</td>
	</tr>
	<tr>
		<td style="background-color:rgb(240,234,162)" class="icons">
		<img src="http://www.winsorgallery.com/images/2/baldwin_1.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/borden_4.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/bos_8.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/cho_10.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/clemens_1.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/dittmar_1.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/gammell_1.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/gleave_3.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/johnston_1.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/seok-lim_1.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/liu_1.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/ostoich_3.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/park-spurr_3.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/plewman_1.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/saito_1.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/son_1.jpg" alt="" />
		</td>
		<td>[Blank]</td>
		<td>Image</td>
		<td>Text</td>
	</tr>
</table>

Now, just adding some styles with our other style declarations will affect everything in that table cell:

.navigation a {display:block;
text-align:center;
width:66px;
text-decoration:none;
padding:2px;
margin-left:16px;
text-transform:uppercase;
margin-bottom:4px;}

.navigation a:link{color:rgb(242,235,183);
border:1px solid rgb(242,235,183);}

.navigation a:hover{color:rgb(148,161,161);
background-color:rgb(242,235,183);
border:1px solid #fff;}

<table border="1" width="640" style="background-color:rgb(130,147,138)">
	<tr>
		<td style="background-color:rgb(240,234,162);width:228px;height:140px">
			Logo</td>
		<td style="width:120px" class="navigation"><a href="#">Artists</a>
		<a href="#">Exhibits</a>
		<a href="#">Press</a>
		<a href="#">About Us</a></td>
		<td style="width:260px">Name</td>
		<td>[Blank]</td>
	</tr>
	<tr>
		<td style="background-color:rgb(240,234,162)" class="icons">
		<img src="http://www.winsorgallery.com/images/2/baldwin_1.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/borden_4.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/bos_8.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/cho_10.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/clemens_1.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/dittmar_1.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/gammell_1.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/gleave_3.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/johnston_1.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/seok-lim_1.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/liu_1.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/ostoich_3.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/park-spurr_3.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/plewman_1.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/saito_1.jpg" alt="" />
		<img src="http://www.winsorgallery.com/images/2/son_1.jpg" alt="" />
		</td>
		<td>[Blank]</td>
		<td>Image</td>
		<td>Text</td>
	</tr>
</table>
Logo Name [Blank]
[Blank] Image Text

One last thing to do here is get rid of the table's border, to be sure it doesn't disrupt the flow of the layout, and clean up the cellpadding and spacing:

<table border="1" width="640" style="background-color:rgb(130,147,138)">

becomes

<table width="640" cellpadding="0" cellspacing="0" style="background-color:rgb(130,147,138)">
Logo Name [Blank]
[Blank] Image Text

Now, just add some content, and the layout is pretty much done:

Vu Dinh Son
Text