A Bulletproof Approach


To bulletproof this table design, let's strip away the excess presentational code from the markup, add accessibility enhancements, and then use CSS to refinish the table. Along the way we'll keep the code light and flexible and still maintain the interesting design.

To begin, let's structure the data with a single table, using the appropriate markupand nothing more. At this point we're focusing on the correct structure for the data being presented; we'll worry about design details in a bit.

THE MARKUP STRUCTURE

Starting with a basic framework, let's mark up the table in order to show the forum name, topics/messages, and the date of the last post. Let's be sure to include each column's heading as well, putting each grouping in its own column.

[View full width]

<table> <tr> <td>Forum Name</td> <td>Topics/Messages</td> <td>Last Post</td> </tr> <tr> <td><a href="/forum/">Name of Forum</a> This is the description of the forum. This is another line of descriptive text.</td> <td>9313/163773</td> <td>Feb 28, 2005 04:21 PM</td> </tr> <tr> <td><a href="/forum/">Name of Forum</a> This is the description of the forum. This is another line of descriptive text.</td> <td>9313/163773</td> <td>Feb 28, 2005 04:21 PM</td> </tr> <tr> <td><a href="/forum/">Name of Forum</a> This is the description of the forum. This is another line of descriptive text.</td> <td>9313/163773</td> <td>Feb 28, 2005 04:21 PM</td> </tr> </table>

The previous markup (with now simplified content for the example) sets up each row and column in the right order. Figure 7.4 shows the results.

Figure 7.4. Here is the default rendering of the table, shown in the Firefox browser.


While everything is in its right place, we can enhance the meaning of the column headers (Forum Name, Topics/Messages, Last Post) by using <th> elements. The purpose of the <th> element is to denote headers for a table's content. That extra level of clarification will help any browser or device better understand how we've organized the table. As an added bonus, this unique element allows us to style those headers differently from other cells using CSSwithout the need for adding extra markup (i.e., a class).

[View full width]

<table> <tr> <th>Forum Name</th> <th>Topics/Messages</th> <th>Last Post</th> </tr> <tr> <td><a href="/forum/">Name of Forum</a> This is the description of the forum. This is another line of descriptive text.</td> <td>9313/163773</td> <td>Feb 28, 2005 04:21 PM</td> </tr> <tr> <td><a href="/forum/">Name of Forum</a> This is the description of the forum. This is another line of descriptive text.</td> <td>9313/163773</td> <td>Feb 28, 2005 04:21 PM</td> </tr> <tr> <td><a href="/forum/">Name of Forum</a> This is the description of the forum. This is another line of descriptive text.</td> <td>9313/163773</td> <td>Feb 28, 2005 04:21 PM</td> </tr> </table>

With <th> elements used for the column headers, we can see that most browsers treat them with a slightly different styleoften bolding and centering the text (Figure 7.5). Remember, we can adjust these effects later using CSS, but right now we're only concerned about optimal structure. Semantically, using <th> elements for "table headers" makes the most sense here.

Figure 7.5. We've added <th> elements to each column's header.


Adding scope

Now that we have table headers in place, we can help users browsing with screen-reading software a bit more by adding the scope attribute. The value of the scope attribute designates which cells belong to the header. For instance, in our example, we use the value col, which specifies that the cells in the column underneath the header are associated with it.

[View full width]

<table> <tr> <th scope="col">Forum Name</th> <th scope="col">Topics/Messages</th> <th scope="col">Last Post</th> </tr> <tr> <td><a href="/forum/">Name of Forum</a> This is the description of the forum. This is another line of descriptive text.</td> <td>9313/163773</td> <td>Feb 28, 2005 04:21 PM</td> </tr> <tr> <td><a href="/forum/">Name of Forum</a> This is the description of the forum. This is another line of descriptive text.</td> <td>9313/163773</td> <td>Feb 28, 2005 04:21 PM</td> </tr> <tr> <td><a href="/forum/">Name of Forum</a> This is the description of the forum. This is another line of descriptive text.</td> <td>9313/163773</td> <td>Feb 28, 2005 04:21 PM</td> </tr> </table>

Similarly, if we'd used a horizontal layout for the table, with the header in front of each cell in a single row, we could use the value row for the scope attribute.

Adding the title

Looking back at Figure 7.2, you can see that we have a title above the table's columns and rows that spans across the entire width. At the Lance Spacerunner example site, this is an image of the text "The Films." We could also use an image here, if we wished, but since my futuristic spacey font collection is a bit thin, we'll just use plain ol' hyper(space?) text for our bulletproof version.

To mark up the table's title, it makes perfectly good sense to utilize the child element of <table> that was designed for the job: the <caption> element. The table's caption sits directly underneath the <table> element, and typically, browsers will center this text above the entire table width (Figure 7.6).

[View full width]

<table> <caption>The Films</caption> <tr> <th scope="col">Forum Name</th> <th scope="col">Topics/Messages</th> <th scope="col">Last Post</th> </tr> <tr> <td><a href="/forum/">Name of Forum</a> This is the description of the forum. This is another line of descriptive text.</td> <td>9313/163773</td> <td>Feb 28, 2005 04:21 PM</td> </tr> <tr> <td><a href="/forum/">Name of Forum</a> This is the description of the forum. This is another line of descriptive text.</td> <td>9313/163773</td> <td>Feb 28, 2005 04:21 PM</td> </tr> <tr> <td><a href="/forum/">Name of Forum</a> This is the description of the forum. This is another line of descriptive text.</td> <td>9313/163773</td> <td>Feb 28, 2005 04:21 PM</td> </tr> </table>

Figure 7.6. The <caption> element is often centered above the table's contents.


tip

There are additional elements we could add to our table, notably <thead>, <tfoot> and <tbody> for grouping rows and giving context to longer table sections. Similarly, <col> and <colgroup> to group columns while allowing browsers to render the table incrementally rather than waiting for the entire table to download.

I recommend reading the W3C's specification on tables (www.w3.org/TR/html401/struct/tables.html), or (perhaps easier to digest) Roger Johansson's "Bring on the tables" article (www.456bereastreet.com/archive/200410/bring_on_the_tables/) to dive into additional markup possibilities for structuring data tables.

Since our table is a short, relatively simplistic table, we're going to move on with the markup as is.


Cellspacing

Before we begin applying CSS, let's add one more bit of markup: the -cellspacing attribute on the <table> element. By assigning the attribute a value of 0, we eliminate any gaps between cells and instead control spacing completely with CSS.

 <table cellspacing="0"> 

Using the cellspacing attribute is the most sure-fire way to give yourself a clean slate when styling tables, but it's not the only way. The CSS property border-collapse exists to essentially achieve the same results that cellspacing="0" does. By specifying

 table {   border-collapse: collapse;   } 

you can keep the <table> element free of attributes. But browser support then becomes a problem. Most browsers support the border-collapse property, but not all (for example, IE/Mac). For this particular example, I don't think it causes much harm to add the cellspacing attribute, so we'll do just that, and move on to adding style.

APPLYING STYLE

With our lean table markup complete, we can now start applying CSS in order to fold in the design. We've already cut in half the amount of markup by removing the extra table cells and keeping only what's needed to structure the data.

To set up the whole page, let's first add a background color and default font and link colors (I'll omit repeating these rules as we move along).

 body {   margin: 0;   padding: 30px;   font-family: "Lucida Grande", Arial, sans-serif;   font-size: small;   background: #b5b5b5;   } a {color: #77985C; } 

Border and background

Next, we'll set a one-pixel black border around the table, and a background color of white. We'll also set the width of the table to 100%, so that it will expand as far as it can. In our example, it'll expand to the width of the browser window (minus the 30 pixels of padding we've previously declared on all sides of the <body> element). In the case of the Lance Spacerunner site, it would expand as wide as the container that it sits in (the main content column of the page).

 table {   width: 100%;   border: 1px solid #000;   background: #fff;   } 

note

Specifying a width of 100% for the table results in a horizontal scrollbar in IE5/Mac. Setting a width that is less than 100% will fix this, or depending on the overall container width that the table will eventually sit inside, omitting a width altogether may be a possibility as welljust letting the table expand as far as it can on its own. The IE5/Mac scrollbar issue is just something to be aware of, but certainly nothing to lose sleep over.


Figure 7.7 reveals our progress thus far.

Figure 7.7. Notice how the <caption> appears outside the table's borders, even though the element is inside.


Padding and dividing line

note

I could've written this declaration by just stating th, td, as these elements are always contained within a <table> element. But for CSS code organization, often I'll use explicit selectorsit's not necessary to specify "cells within table elements," but it's a simple way of visually grouping declarations in your stylesheets.


Next, we'll add padding within each <th> and <td> element, and create the single-pixel gray line that divides each row:

 table {   width: 100%;   border: 1px solid #000;   background: #fff;   } table th, table td {   margin: 0;   padding: 8px 20px;   text-align: center;   border-bottom: 1px solid #b5b5b5;   } 

Figure 7.8 shows the added 8-pixel padding on top and bottom, the 20-pixel padding on both sides, as well as the gray lines separating the rows that span across the entire table. By adding a border-bottom to each cell, we achieve a continuous straight line. This works only when cellspacing is zeroed out (as we've done) or if border-collapse: collapse; is specified for the <table> element. We've also centered text within all cellssomething we'll want to override for the "Forum Name" column only.

Figure 7.8. Because we've removed cellspacing, a consistent line can be achieved by assigning borders to the cells.


Custom alignment

To left-align the text for only the "Forum Name" header and the column underneath, let's create a class that we can attach to those elements that overrides the text-align: center; previously declared.

 table {   width: 100%;   border: 1px solid #000;   background: #fff;   } table th, table td {   margin: 0;   padding: 8px 20px;   text-align: center;   border-bottom: 1px solid #b5b5b5;   } table .name {   text-align: left;   } 

Once we've created a generic name class, we can attach it to the appropriate spots in the markup:

[View full width]

<table cellspacing="0"> <caption>The Films</caption> <tr> <th scope="col" >Forum Name</th> <th scope="col">Topics/Messages</th> <th scope="col">Last Post</th> </tr> <tr> <td ><a href="/forum/">Name of Forum</a> This is the description of the forum. This is another line of descriptive text.</td> <td>9313/163773</td> <td>Feb 28, 2005 04:21 PM</td> </tr> <tr> <td ><a href="/forum/">Name of Forum</a> This is the description of the forum. This is another line of descriptive text.</td> <td>9313/163773</td> <td>Feb 28, 2005 04:21 PM</td> </tr> <tr> <td ><a href="/forum/">Name of Forum</a> This is the description of the forum. This is another line of descriptive text.</td> <td>9313/163773</td> <td>Feb 28, 2005 04:21 PM</td> </tr> </table>

Figure 7.9 shows the results. The text and heading for the "Forum Name" column are left-aligned but the other two columns are centered.

Figure 7.9. Since the "Forum Name" column is the exception, we left-aligned these cells by adding a class.


Alternating row colors

A little extra markup is also necessary to handle the alternating row colors from the original Lance Spacerunner design (unless you don't mind using a bit of JavaScript to dynamically handle this; see "Zebra Tables," www.alistapart.com/articles/zebratables/). We want to denote the alternate row color by adding a class to the desired <tr> elements.

I like to use the value alt for these situations, staying away from values named gray or dark or any other visual description. This keeps the class name generic enough to be used wherever desired. If the alternate color is gray today, it doesn't mean that color won't change in the future to green (or anything else) and thus result in a confusing class name.

[View full width]

<table cellspacing="0"> <caption>The Films</caption> <tr> <th scope="col" >Forum Name</th> <th scope="col">Topics/Messages</th> <th scope="col">Last Post</th> </tr> <tr > <td ><a href="/forum/">Name of Forum</a> This is the description of the forum. This is another line of descriptive text.</td> <td>9313/163773</td> <td>Feb 28, 2005 04:21 PM</td> </tr> <tr> <td ><a href="/forum/">Name of Forum</a> This is the description of the forum. This is another line of descriptive text.</td> <td>9313/163773</td> <td>Feb 28, 2005 04:21 PM</td> </tr> <tr > <td ><a href="/forum/">Name of Forum</a> This is the description of the forum. This is another line of descriptive text.</td> <td>9313/163773</td> <td>Feb 28, 2005 04:21 PM</td> </tr> </table>

We first define a default row color of gray for all <tr> elements; then we override that value with a lighter shade for alternating rows marked with the alt class:

 table {   width: 100%;   border: 1px solid #000;   background: #fff;   } table th, table td {   margin: 0;   padding: 8px 20px;   text-align: center;   border-bottom: 1px solid #b5b5b5;   } table .name {   text-align: left;   } table tr {   background: #e6e6e6;   } table tr.alt {   background: #f1f1f1;   } 

Figure 7.10 shows the alternating row colors, and as you can see things are starting to look rather nice.

Figure 7.10. Instead of alt we could've used a color or other description, but keeping it generic is always a good idea in case color or appearance changes later on.


New line without the <br/>

To get each forum name and description on its own line, rather than drop in a <br /> element we could specify links within <td> elements of our table to use the display: block; property. This way, we force the description that comes after it to start on the line belowwith no extra markup needed. While we're at it, let's make those links bold as well:

 table {   width: 100%;   border: 1px solid #000;   background: #fff;   } table th, table td {   margin: 0;   padding: 8px 20px;   text-align: center;   border-bottom: 1px solid #b5b5b5;   } table .name {   text-align: left;   } table tr {   background: #e6e6e6;   } table tr.alt {   background: #f1f1f1;   } table td a {   display: block;   font-weight: bold;   } 

As Figure 7.11 shows, each link is now bold and on its own line as a result of the added declaration. Using the display: block; rule to force items onto separate line without using a <br /> is a nice trickbut only if the content still makes sense when CSS is taken away. In this particular case, I think devices that don't support CSS will understand the link and description that follows just fine.

Figure 7.11. Using display: block; on the link works here, as long as there are no other links within the same cell, since those would be forced onto their own lines as well.


note

Setting display: block; on a link, as we've just done, extends the clickable area of that link to the entire width of its parent container. In other words, the entire line (whether the text extends all the way or not) is clickablenot just the text itself. This could be seen as a usability improvement, giving the user a larger area to click on. Whether or not it's useful could be debated, but it's something that's worthy of pointing out, should you decide to use this method for forcing text onto its own line when links are involved.


Header color

As mentioned earlier, one of the side benefits of using table headers (<th>) properly is that doing so gives you control over these elements in terms of stylewithout the need for extra markup in the way of classes.

For instance, in the Lance Spacerunner example, table headers are a lighter shade of gray than the rest of the table's textand we can easily match that by adding a simple rule to turn all <th> elements the color we wish:

 table {   width: 100%;   border: 1px solid #000;   background: #fff;   } table th, table td {   margin: 0;   padding: 8px 20px;   text-align: center;   border-bottom: 1px solid #b5b5b5;   } table th {   color: #999;   } table .name {   text-align: left;   } table tr {   background: #e6e6e6;   } table tr.alt {   background: #f1f1f1;   } table td a {   display: block;   font-weight: bold;   } 

Figure 7.12 shows the results of adding the declaration. The table headers are now gray, as opposed to the default black.

Figure 7.12. We needed to turn the column headers a different color, and it was painless because we used proper <th> elements to structure them.


Styling <caption>

Next, let's style the <caption> element, giving it a white background and adding a border on three sides (omitting the bottom border, since that's already part of the <table>).

We originally chose to use the <caption> element for the title of the table for semantic reasons. It's the markup choice that makes the most sense. Safari and IE/Mac treat the styling of <caption> differently than other browsers; you may get mixed results depending on the styles you choose to apply. For instance, in our example the <caption> appears to be several pixels less wide than the <table> itself, even though <caption> is contained within the <table> element. This could be the result of odd behavior, or a different interpretation of the specification. Either way, use your judgment when choosing to use either the <caption> (the optimal choice) or another element (i.e., a heading element).

 table {   width: 100%;   border: 1px solid #000;   background: #fff;   } table caption {   margin: 0;   padding: 8px 20px;   text-align: left;   border: 1px solid #000;   border-bottom: none;   background: #fff;   } table th, table td {   margin: 0;   padding: 8px 20px;   text-align: center;   border-bottom: 1px solid #b5b5b5;   } table th {   color: #999;   } table .name {   text-align: left;   } table tr {   background: #e6e6e6;   } table tr.alt {   background: #f1f1f1;   } table td a {   display: block;   font-weight: bold;   } 

By default, a table's caption is centered, so in addition to some padding, background, and border on all sides but the bottom, we're left-aligning the text (Figure 7.13). Again, the Lance Spacerunner example featured a graphic for the words "The Films" that could also be located within the <caption> element in place of the plain text that we're using.

Figure 7.13. The caption is styled nicely in the Firefox browser.


The offset shadow

For the offset drop shadow on the entire table, Lance Spacerunner added an extra column and row, placing graphics in those cells to create the shadow effect (Figure 7.14). We're going to achieve the same resultwithout adding unnecessary cells and using no graphics at all.

Figure 7.14. The offset effect that's essential for drop shadows is possible by using an additional outer element around the table.


We will, however need to add a containing <div> around the table, one that will fill in the shadow color as a background. We'll then bump the table out of the container's edges by 4 pixels, using a little positioning.

So, our markup will change slightly with the addition of a <div> wrapped around the table. Let's begin by defining a class for this wrapper that we can reuse for additional tables on the page:

 <div >   <table cellspacing="0">   ...   </table> </div> 

We'll assign the shadow color as a background for the entire containing <div>. However, with the table sitting inside this container, the background color will be completely obscured. To reveal that background behind the table on the right and bottom edges, as well as achieve the offset on the top-right and bottom-left corners, we need to use a little negative positioning to nudge the table (Figure 7.15).

Figure 7.15. Using negative positioning to nudge the table up and to the left by a few pixels, the containing <div>'s background will be revealed on the bottom and right sides.


So first, we add the background color (a dark gray) that we'd like the shadow to be on the containing <div> in a new declaration:

 .forums {   background: #919191;   } 

Next, we'll add the negative positioning to the main <table> declaration, nudging the entire table exactly 4 pixels up and to the left:

 .forums {   background: #919191;   } table {   position: relative;   top: -4px;   left: -4px;   width: 100%;   border: 1px solid #000;   background: #fff;   } table caption {   margin: 0;   padding: 8px 20px;   text-align: left;   border: 1px solid #000;   border-bottom: none;   background: #fff;   } table th, table td {   margin: 0;   padding: 8px 20px;   text-align: center;   border-bottom: 1px solid #b5b5b5;   } table th {   color: #999;   } table .name {   text-align: left;   } table tr {   background: #e6e6e6;   } table tr.alt {   background: #f1f1f1;   } table td a {   display: block;   font-weight: bold;   } 

By using position: relative here, we'll adjust the position of the table from the spot on the page where it already lies, as opposed to position: absolute, which would position the table in terms of the coordinates of its parent container.

Using a negative value here will "nudge" the table out from the <div> that wraps it, revealing 4 pixels of its background on the right and bottom, as well as the offset that creates the shadow effect (Figure 7.16).

Figure 7.16. The completed design features a graphic-free drop shadow.




Bulletproof Web Design(c) Improving flexibility and protecting against worst-case scenarios with XHTML and CSS
Bulletproof Web Design(c) Improving flexibility and protecting against worst-case scenarios with XHTML and CSS
ISBN: N/A
EAN: N/A
Year: 2006
Pages: 97

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net