Tables

We will start discussing the <table> element by talking about its original use - to display tabular data. While there are times you will want to use tables to assist you in laying out a page, stylesheets are the forward-looking approach.

Consider the following table:

Travel Specials
FromToOne WayRound Trip
San JoséLas Vegas$29.00$50.00
San FranciscoChicago$150.00$275.00
Los AngelesSeoul$750.00$1500.00
ChicagoAmsterdam$450.00$850.00

The words Travel Specials are the table’s caption. The table itself has five rows, and each row has four cells. The first row of the table consists of header cells, which are automatically bold and centered. The rest of the rows consist of data cells, which are plain text, left-justified.

Table Borders

In older versions of HTML, you could show the borders around the cells in a table by setting the border="1" attribute on the <table> tag. However, since HTML5 now separates content and presentation, you must use styles to put borders on your table. On this page, I have used the following style. Don’t worry about the th and td selectors, they will be explained shortly.

<style type="text/css">
   table, th, td { border: 1px solid black; }
</style>

In terms of HTML, the table begins as shown below. Whenever you first start a table, set your styles so that the borders are turned on. This will help you see exactly where everything is laid out. In the event that your table looks better without borders, you can always remove the styles. when you finish the table. The ending </table> tag is required. If you leave it off, the table won’t display properly.

<table>
<caption>Travel Specials</caption>

 <!-- table contents go here -->

</table>

Just as with a document, you may have a table header and the table body. In this case, the first row of the table is the table heading, and the rest is the table body. You mark the table’s head and body with the <thead> and <tbody> elements.

The contents of a row are enclosed in <tr> elements. Header cells are marked with <th>, and data cells with <td>. Although the ending tags for all of these three are technically optional, we will require them in this course. Here is the HTML for the first three rows of the table. Notice that we are using indenting to keep the table readable. Proper use of whitespace and indenting is useful for a small table like this one; it is vital for any complex table.

<table>
<caption>Travel Specials</caption>
<thead>
   <tr>
      <th>From</th>
      <th>To</th>
      <th>One Way</th>
      <th>Round Trip</th>
   </tr>
</thead>

<tbody>
   <tr>
      <td>San Jos&#233;</td>
      <td>Las Vegas</td>
      <td>$29.00</td>
      <td>$50.00</td>
   </tr>

   <tr>
      <td>San Francisco</td>
      <td>Chicago</td>
      <td>$150.00</td>
      <td>$275.00</td>
   </tr>

   <!-- etc. -->
</tbody>
</table>

There’s nothing mysterious about tables at this point. Everyone sees quite clearly how they are constructed. The trick to making tables more flexible is in the styling. For example, we were able to put borders on the table by giving the <table>, <th> and <td> elements a one pixel solid black border.

Table Widths

Notice that the table above takes up exactly as much room as is needed to show the data; no more, no less. Sometimes you will want the table to be wider. You can set the width property on the table to either:

Try both of these and see what they do. Resize the browser window; see what happens as you reduce the window width. My personal preference is to use percentages. I have seen too many websites that presumed that everyone has a 1024 x 768 monitor, so they set their table width to 1000, which means I have to scroll horizontally on my 800 x 600 monitor in order to see their content. Don’t do this to your readers.

Cell Widths

You may set the widths of individual cells within a row, again either in terms of pixels or in terms of percentages. You need to set the widths on only one row, usually the first row. Try pixel widths first.

<table>
<thead>
   <tr>
	  <th style="width: 200px">From</th>
	  <th style="width: 200px">To</th>
	  <th style="width: 100px">One Way</th>
	  <th style="width: 100px">Round Trip</th>
</tr>
</thead>

Now try percentages and see how it works. Again, make sure you resize the window to see what effect it has.

<table style="width: 90%">
<thead>
   <tr>
	  <th style="width: 35%">From</th>
	  <th style="width: 35%">To</th>
	  <th style="width: 15%">One Way</th>
	  <th style="width: 15%">Round Trip</th>
   </tr>
</thead>

It is possible to set your table width to a fixed number of pixels and use percentages for the cells within each row. While it is also possible to mix percentage and pixel widths for cells, it’s unusual to see it in practice. If your percentages add up to a value that is not 100%, the browser will scale them proportionately. Don’t count on that behavior—do the math first.

Aligning the Table

To align the table with respect to the browser window, you must use set the table’s margin properties to auto, which tells the browser to accomodate the margin to fit the width of the windows. To center a table on the page, set both margin-right: auto; and margin-left: auto;. To right-align a table, set only margin-left: auto;. Try it and find out..

To align the contents of a cell, set the appropriate text-align property to that cell’s style. To align the contents of the cells of an entire row, add the set the appropriate text-align property to the opening <tr> tag’s style. See if you can figure out what the following changes will do to the table, then try it.

<table style="width: 90%">
<thead>
   <tr>
      <th style="width: 35%">From</th>
      <th style="width: 35%">To</th>
      <th style="width: 15%">One Way</th>
      <th style="width: 15%">Round Trip</th>
</tr>
</thead>
<tbody>
   <tr style="text-align: center">
      <td>San Jos&#233;</td>
      <td>Las Vegas</td>
      <td style="text-align: right">$29.00</td>
      <td style="text-align: right">$50.00</td>
   </tr>
   <tr style="text-align: center">
      <td>San Francisco</td>
      <td>Chicago</td>
      <td style="text-align: right">$150.00</td>
      <td style="text-align: right">$275.00</td>
   </tr>
   <!-- etc. -->
</tbody>
</table>

Vertical Alignment

If two cells in the same row have content of a different height, the vertical alignment is centered. For example, change the San Francisco to Chicago row to indicate that it goes into Midway airport rather than O’Hare (please try it).

<tr align="center">
   <td>San Francisco</td>
   <td>Chicago <br /> (Midway)</td>
   <td style="text-align: right">$150.00</td>
   <td style="text-align: right>$275.00</td>
</tr>

Most of the time, this is exactly what you want. Sometimes you will want the content aligned at the top of the cells and occasionally at the bottom of the cell. To do this, you set the vertical-align property to top or bottom. The default value is middle. Try this change, and see the effect on the row.

<tr align="center" >
   <td style="vertical-align: top">San Francisco</td>
   <td>Chicago <br /> (Midway)</td>
   <td style="text-align: right; vertical-align: "bottom">$150.00</td>
   <td style="text-align: right; vertical-align: "middle">$275.00</td>
</tr>

By the way: this is the first time you have seen a table cell with other HTML elements inside it rather than just plain text. It turns out that you can have almost anything inside a cell. You can put paragraphs, images, links, and, as you will see in future notes, even other tables into a table cell.

Colorizing Your Tables

It is possible to set the background-color property for the style of an entire table, a whole row, or a single cell, by applying the attribute at the desired level. The following changes will set the entire table to a light aqua background, except for the San José to Las Vegas row, which will have a bisque background color, except for the one-way fare cell in that row, which will be a bright yellow.

<table border="1" style= background-color: #ccffff">
<thead>
   <tr>
      <th style="width: 35%">From</th>
      <th style="width: 35%">To</th>
      <th style="width: 15%">One Way</th>
      <th style="width: 15%">Round Trip</th>
   </tr>
</thead>
<tbody>
   <tr style="text-align: center; background-color: #ffcc99">
      <td>San Jos&#233;</td>
      <td>Las Vegas</td>
      <td style="text-align: right; background-color: yellow">$29.00</td>
      <td style="text-align: right">$50.00</td>
   </tr>
   <tr align="center">
      <td>San Francisco</td>
      <td>Chicago<br />(Midway)</td>
      <td align="right">$150.00</td>
      <td align="right">$275.00</td>
   </tr>
   <!-- etc. -->
</tbody>
</table>

Setting a Background Image

You may also set a background image on a cell, row, or entire table. Try this. Here are links to the light blue image, the W3C logo image, and an image of an arrow pointing to the right so that you may copy them to an appropriate directory. Change the pathname to match the directory where you place your images.

<table style="background: url(images/lblue.jpg)">

<!-- first two rows remain the same -->

<tr style="background: url(images/w3c_home.png)">
   <td>San Francisco</td>
   <td style="background: url(images/right.png)">Chicago<br />(Midway)</td>
   <td>$150.00</td>
   <td>$275.00</td>
</tr>

<!-- etc. -->

</table>

Cell Spacing and Padding

You will notice that the cells of the table are right next to one another, and text comes right up to the cell borders. Making more space inside each cell is easy; just add the appropriate padding property on the cell’s style. Change the <style> for the sample table to read as follows. The padding has been set large to show you the effect as dramatically as possible.

<style type="text/css">
   table {
     1px solid black;
   }
   th, td {
     border: 1px solid black;
     padding: 15px;
   }
</style>

Setting the amount of space between the cells is not so easy. You cannot just set the margin property; that does not work. Instead, you must set the border-spacing property on the style of the <table> element. Try this internal stylesheet and see what happens.

<style type="text/css">
   table {
      1px solid black;
      border-spacing: 15px; }
   th, td {
      border: 1px solid black;
   }
</style>

Column and Row Spans

Take a look at the “split-level” effect of the heading on the following table.

From To Discount Fares
One WayRound Trip
San JoséLas Vegas$29.00$50.00
San FranciscoChicago$150.00$275.00
Los AngelesSeoul$750.00$1500.00
ChicagoAmsterdam$450.00$850.00

We are going to show you a method that makes table layouts like this easy to construct. This method was in the older editions of an HTML book by Elizabeth Castro. I have no idea why it was taken out.

  1. Draw a sketch of what the table should look like on a piece of paper. (See illustration) You do not pay for connect time to paper and pencil! You don’t have to fill in every detail; an outline showing the borders is sufficient.

  2. Everywhere you see a line in the table, extend it all the way to the edges of the table. (See illustration) It helps to use a different color pen to do this. If your table is really complicated, use a straightedge to make sure the lines are accurate.

    As you can see in the illustration, this table actually has six rows of four cells each. Let’s call these the “guide” lines.

    The header cells From and To have their upper left corner in row 1 and their lower right corner in row 2; that means they spread across two rows. The header Discount Fares has its upper left corner in column 3 and its lower right corner in column 4; thus, it spans two columns. You will thus use the rowspan and colspan attributes in the appropriate cells.

    The rule: to figure out whether a table cell (outlined in black in the illustration) spans rows or columns, look at the upper left and lower right corner, and see if it crosses any of the “guide” lines (the red lines).

  3. Now begin entering the table. Draw an arrow next to the row you’re working on. As you finish each cell, cross it off entirely (See illustration).

    <table>
    <thead>
       <tr>
          <th rowspan="2">From</th>
  4. Continue entering cells; when you hit the end of a row, put a bar at the end of the row to indicate that it is finished. Move your arrow down to the next line. (See illustration).

    <table>
    <thead>
       <tr>
          <th rowspan="2">From</th>
          <th rowspan="2">To</th>
          <th colspan="2">Discount Fares</th>
       </tr>
  5. This is where the crossing-off starts to make sense. Notice that the first cell that you need to handle in the second row is the One Way cell. (See illustration)

    <table>
    <thead>
       <tr>
          <th rowspan="2">From</th>
          <th rowspan="2">To</th>
          <th colspan="2">Discount Fares</th>
       </tr>
       <tr>
          <th>One Way</th>
  6. And then, finish the row. Once you go to the third row, you can see that the red and black lines are all on top of each other; there are no more row or column spans, so you can just transcribe the remainder of the table as before. (See illustration)

    <table>
    <thead>
       <tr>
          <th rowspan="2">From</th>
          <th rowspan="2">To</th>
          <th colspan="2">Discount Fares</th>
       </tr>
       <tr>
          <th>One Way</th>
          <th>Round Trip</th>
       </tr>
    </thead>

You may be thinking, “Well, who needs to go to all that work? I could have laid out this table by eye, no problem.” The nice part of this method is that it works no matter how complicated your table is. Consider the following table. I wouldn’t even try to figure this one out by eye; with the method shown here, it took me all of two minutes to draw and two minutes to type, and it worked the first time.

complex table with many spanned rows and columns

Nested Tables

We said that a table cell can contain almost anything, and that includes another table. When you’re presenting tabular data, this is almost never necessary, but here is a demonstration to show that yes, it does work.

<table>
<tbody>
<tr>
    <td>Row one, cell one</td>
    <td>Row one, cell two</td>
    <td>Row one, cell three</td>
</tr>
<tr>
    <td>Row two, cell one</td>
    <td>
        Row two, cell two
        <table>
        <tbody>
        <tr>
            <td>inner A</td><td>inner B</td>
        </tr>
        <tr>
            <td>inner C</td><td>inner D</td>
        </tr>
        </tbody>
        </table>
    </td>
    <td>Row two, cell three</td>
</tr>
</tbody>
</table>

And here’s what it looks like:

Row one, cell one Row one, cell two Row one, cell three
Row two, cell one Row two, cell two
inner Ainner B
inner Cinner D
Row two, cell three