In two of my recent posts, I demonstrated using ASP.NET AJAX in conjunction with jQuery or ASP.NET AJAX 4.0’s templating features to generate client side tables from JSON data. However, what I neglected to show you was how to make them look even remotely presentable.

In this post, we’ll continue where those posts left off. I’m going to show you how you can improve the table’s presentation in three steps:

  • Setting basic styles for the page and table.
  • Improving the table header by using strong contrast.
  • Adding subtle gridlines to the table body.


A humble beginning and a basic foundation

At the end of both my previous posts on client-side templating, you were left with an HTML table that looked like this:

Though the table’s semantic structure is excellent, it is visually abysmal. Luckily, the table’s markup is very well suited to extensive CSS styling, so improving its presentation will be relatively painless.

Getting started, I’m going to apply styles to the container div and root table element, giving them a fixed width and centering them. I’ll also specify a better font than Times New Roman:

/* No one likes Times New Roman, including me. */
body { font-family: "Trebuchet MS", Serif; }
 
/* Gives the container a fixed
width and centers it on the page. */
#Container { margin: 0 auto; width: 900px; }
 
/* Expand the table to fill the container, and
add a 2px black border around its outside edge. */
table { width: 100%; border: 2px solid #000; }

Note that adding this border style to the table through CSS is not the same as setting the table element’s border attribute to 2. This CSS will add a border only to the outside of the table, whereas the table’s border attribute would add borders around and between every cell.

Use contrast to improve the <thead>

By default, most browsers will render a <thead>’s <th> elements in a bold and slightly larger font style. That’s a good start, but we can do better:

table thead tr th {
/* Set the heading's background image to something nice.
Use a similar background color, to maintain continuity. */
background-color: #000;
background-image: url(images/black-gradient.png);
 
/* Set the foreground color to something readable on black. */
color: #FFF;
 
/* Give the heading a larger, bold style */
font-size: 18px;
font-weight: bold;
 
/* Finally, make it the same height as the background image. */
height: 35px;
}

This styling makes the <thead> area of the table look like this:

The dark background and reversed text both help to strongly define the heading row and draw your eye to the table’s intended starting point. Unless you have a captive audience, minimizing the time your users spend visually scanning the page is vitally important.

Since the background image covers the entire height of the <thead>, setting a background color may seem redundant, but is a good precaution. In case the image loads slowly, times out, or even 404s, your table is still usable.

Subtle improvements to the <tbody>

The net benefit of zebra striping and gridlines inside table bodies has been a point of contention lately. I’m not entirely sold on zebra striping myself, but believe that subtle gridlines between table cells are a great usability gain.

table tbody td {
/* Pure black is harsh on a white background. Soften slightly. */
color: #333;
 
/* Give the <td> cell content some breathing room. */
padding: 4px;
 
/* Create the illusion of gridlines between the cells. */
border-top: 1px solid #CCC;
border-left: 1px solid #CCC;
}

The top and left cell borders fit together to give the illusion of continuous gridlines, similar to what the GridView produces:

Using pseudo selectors to remove a minor artifact

One drawback of applying a top and left border to all of the table cells is that the cell borders overlap against the table’s borders on the top and left edge of the table body. In the color scheme I’ve chosen for this example, the artifact is barely visible, but that won’t be the case in every implementation.

We can use CSS’ :first-child pseudo class to remove those redundant borders:

/* Remove the border from the top row. */
table tbody tr:first-child td { border-top: none; }
 
/* Remove the border from the left column. */
table tbody tr td:first-child { border-left: none; }

Compared to most CSS, the :first-child and :last-child pseudo selectors tend to be abnormally confusing. This rule of thumb may help you:

Element:first-child does not mean that the style will be applied to the element’s first child. Instead, :first-child means that the style will be applied if the element is the first child of its own parent element.

Note: These pseudo selectors do not work in IE6, but fail gracefully. If you’re still supporting a large number of IE6 users, you might want to investigate altogether different methods of implementing the gridlines (there are several).

Conclusion

As you’ve now seen, a small amount of CSS goes a long way toward making your tables presentable. I think it’s always preferable to style tables this way, but even more so when generating them on the client-side. The last thing you want to do is mix presentation with markup and complicate the templating process.

I had hoped to squeeze client-side sorting into this post, but ran out of space and time. So, I’ll be continuing this series at least one more post, showing you how to implement client-side sorting and paging for these templating examples.

I think once you see the series concluded, you’ll never again consider using a sluggish UpdatePanel and GridView in heavily trafficked areas of your apps. The performance difference is truly astounding to see firsthand.

As always, subscribe via RSS or email to make sure you don’t miss a post.

Get the source

The source download for this post also includes client-side sorting. Enjoy.

Source download: styled-client-repeater.zip (31kb)