Tutorial: Styling a Table

HTML is great for building tables, but you need CSS to give them style. As you can see on Using Tables the Right Way, it takes quite a bit of HTML to construct a simple table. Lucky for you, this book comes with a prebuilt HTML table for you to practice your CSS on. In this tutorial, you'll format the table's rows, columns, and cells, and give it an attractive font and background color.

To get started, download the tutorial files located on this book's companion website at www.sawmac.com/css2e/. Click the tutorial link and download the files. All the files are enclosed in a ZIP archive, so you need to unzip them first. (Go to the website for detailed instructions.) The files for this tutorial are in the 10table folder.

  1. Launch a web browser and open the file 10tabletable.html.

    This page contains a simple HTML table. It has a caption, a row of table headers, and nine rows of data contained in table cells (Figure 10-9). In addition, the <col> tag is used three times to identify the three columns of data. As you'll see in a bit, <col> is a handy tag to style, since it will let you set the width of all cells in a column.

  2. Open table.html in a text editor.

    You'll start by creating a style that sets the table's width and text font. This table has an ID of inventory applied to it, so you can use an ID selector to format just this one table.

  3. Click between the opening and closing <style> tags, and then add the following style:

    #inventory {
      font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
      width: 100%;
    }

    Unless you set the width of a table, it grows and shrinks to fit the size of the content inside it. In this case, you've set a 100 percent width, so the table stretches to fit the entire width of its containing <div>. (In this case, it's the area of the page containing the headline "Welcome to the Lorem Ipsum Store" and the table itself.) Setting the font family in the <table> uses inheritance to give all of the tags inside the table the same font—<caption>, table headers (<th>), table cells (<td>), and so on.

    Next you'll style the table's caption.

  4. Add another style below the table style you just created:

    #inventory caption {
      text-align: right;
      font-size: 1.3em;
      padding-top: 25px;
    }

    This descendent selector only affects the <caption> tag that appears inside another tag with the ID of inventory (that's the <table> on this page). A <caption> tag indicates what a table is about. In this case, it shouldn't be the focus of attention, so you've kept the text small and moved it to the right edge, out of the way. The padding-top property adds some space above the caption, moving the caption (and table) a bit farther below the headline.

    When you read information across a table row, it's easy to lose track of which row you're looking at. Good visual guides are essential. Adding borders around the cells, which you'll do next, visually delineates the information.

  5. Add the following group style to the internal style sheet:

    #inventory td, #inventory th {
      font-size: 1.4em;
      border: 1px solid #DDB575;
    }

    This group selector formats the table header (<th>) and table cell (<td>) tags of this table with larger type and draws a border around each header and each cell. Browsers normally insert space between each cell, so at this point there are small gaps between the borders (Figure 10-10, circled). Between the gaps and the borders, the whole table looks too boxy. You'll fix that next.

  6. Add the border-collapse property to the table style you created in step 3 so that it looks like this:

    #inventory {
      font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
      width: 100%;
     border-collapse: collapse;
    }

    The border-collapse property removes the spacing between cells. It also merges borders that touch, which prevents thick, unattractive borders. Without border-collapse, the bottom border of a table header and the top border of the table cell would double up to make a 2-pixel border.

    If you preview the table now, you'll see the data is better organized visually, but the information in each cell looks a little cramped. Add some padding to fix that.

  7. Add padding to the group selector you created in step 5:

    #inventory td, #inventory th {
      font-size: 1.4em;
      border: 1px solid #DDB575;
      padding: 3px 7px 2px 7px;
    }

    While the top, table-header row stands out because of its boldface text, there are a few things you can do to make it stand out even more and improve its appearance.

  8. Create a new style below the #inventory td, #inventory th style for formatting just table head cells:

    #inventory th {
      text-transform:uppercase;
      text-align: left;
      padding-top: 5px;
      padding-bottom: 4px;
    }

    This style is a perfect example of effective cascading. The group selector td, th defines common formatting properties between the two types of cells. By introducing this th-only style, you can further tweak the look of just the table headers. For example, the padding-top and padding-bottom settings here override those same settings defined in the selector in step 7. However, since you don't override the left or right padding settings, the <th> tags will retain the 7 pixels of left and right padding defined in step 7. This style also turns all of the text to uppercase and aligns it to the left edge of the table cell.

    The table headers still don't have enough oomph, and the table seems to recede into the background of the page. A background graphic can provide the necessary boost.

  9. Edit the th style by adding a background image and changing the text color:

    #inventory th {
      text-transform:uppercase;
      text-align: left;
      padding-top: 5px;
      padding-bottom: 4px;
      background: url(images/bg_th.png) no-repeat left top;
      color: #FFF;
    }

    In this case, the graphic introduces a subtle top-down gradient while a white borderline at the top and left edges of the image contrasts nicely with the darker top and left borders around the cells, giving the cells a 3-D look.

    When tables have lots of data stuffed into many rows and columns, it's sometimes hard to quickly identify which data belongs to each row. One solution designers use is to alternate the color of every other row in a table. You create this effect with a class style that you apply to every other table row.

  10. Add one more style to the web page's internal style sheet:

    #inventory tr.alt td {
      background-color: #FFF;
    }

    This complex descendent selector basically says, "Apply the following formatting to every <td> tag that's inside a <tr> tag that has the class alt applied to it and only when both of those are inside another tag with the ID of inventory." The style itself will turn the background of the cells to white, but in order for it to work, you must first apply the class alt to every other row.

  11. In the page's HTML, look for the <tr> tag that precedes the <td> containing "Vitae Quam Lorem." Add class="alt" to that <tr> tag, like so:

    <tr class="alt">
    <td>Vitae Quam Lorem</td>

    You'll need to do this with every second row after this one as well. (Manually tagging each alternating row can be tedious, especially if you frequently add or reorder table rows. For an automated approach to striping table rows using a little JavaScript programming, see the Tip on Styling Rows and Columns.)

  12. Repeat step 11 for every other <tr> tag.

    You'll probably want to check the page in a browser after you add the class to each <tr>, just to make sure you're correctly locating every other table row.

    Finally, you'll adjust the width of the cells that fall under the Price and Rating columns. One technique is to meticulously add class names to those cells and create a class style with a set width. A better approach, however, is to take advantage of the <col> tag, which lets you assign a class or ID to a column's worth of cells. As you can see in Figure 10-9, those two columns have an ID of price and rating. You can easily set the width for these two columns with one group selector.

  13. Add one more style to the web page's internal style sheet:

    #price, #rating {
      width: 100px;
    }

    Now those two columns are each 100 pixels wide. Finally, the table looks great in all browsers…well almost. In IE 6, the table drops down on the page. When the table's width is set to 100 percent, IE 6 actually makes the table a little bit larger than its container, which in turn forces the table to drop down below the left sidebar. This all-too-common problem is called a float drop, and you'll learn more about it on Preventing Float Drops. But for now, a simple solution is to just make the table slightly smaller than 100 percent.

  14. Edit the ID style #inventory, used to format the table, by changing the width to 98 percent, like this:

    #inventory {
      font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
      width: 98%;
      border-collapse: collapse;
    }

    Now the table is just a tad thinner than its container and fits fine in IE 6. (If you simply can't stand the table being thinner in other browsers, you could use an IE 6–specific style to only set the width to 98 percent for that one browser—see Isolate CSS for IE with Conditional Comments for more on that trick.)

Preview the page in a web browser to see the results. Your page should look like the bottom image in Figure 10-9. You'll also find the completed exercise in the 10_finishedtable folder.