Accessible Smart Tables

Posted July 4th, 2005 by Mike Cherim

This is sort of out of date. The tech is okay, but the colors I used are poor choices.

Today, class, we will build some “Accessible Smart Tables.” First you will need to gather some two-by-fours… oh, wait, wrong class. All we’ll need here is Notepad or another text editor for writing our code. I will show you how to build a table with web accessibilities in mind, and it’ll be a table with a bit more functionality and style than one would normally have. But, first, let’s have a brief look at tables and the purpose they serve, then we’ll address how to make them better.

Tables consist of rows and columns and are meant to organize certain data which is best viewed in that form to ensure better comprehension of said data. The common web table has been around since the beginning — carried over from print. And just like in print, you can get creative with web tables my modifying background colors, border attributes, size, position, size of elements, all sorts of good stuff. The table is pretty easy to manipulate, which explains why it’s been done so much on the web — taken to the nth degree it has. Developers, in fact, have taken the lowly table to new heights but using a ton of creativity. Don’t believe me? Visit some web sites, view the source, see the tables. There you have it. And don’t bother looking for the tabular data, it’s not there. Instead you’ll find text, images, multimedia, anything, and everything. It seems that the table is rarely used for what it’s meant to be used for anymore. You’ll even see tables within tables. It should be noted, however, that these are not good tables and they lack accessibility. Why? Because tabular data is supposed to be within the tables and tables are supposed to be within the web page. Not the other way around.

This article isn’t about the table manipulation described above, it’s about styling and coding a proper table, one which resides within a web page — not as the web page itself — one that contains data, data which should be in a table. I plan to show you how to take this kind of table and make it more usable, user-friendly, readable, better. An “Accessible Smart Table.”

Let’s start with the basics. A table consist of the following elements.

  • The table itself <table></table>.
  • The table’s heading <th></th>.
  • The table rows <tr></tr>.
  • The columns which intersect the rows forming table data cells <td></td>.

Other rarely-used elements should be included if you want to make the table as accessible as possible. Certain groups will use or even rely on these elements. Namely:

  • The table summmary summary=""
  • The table caption <caption></caption>.

Below is an example of the HTML used to build a basic table. Please note that the width, border, cellspacing, and cellpadding are required with the table itself. A table is a construction and as such one must define the construction parameters so the browser knows how to build it, with styles enabled or without. This is why you will not find things like “colspan” in the CSS. (That’s right, the browser has to build the table from the information you provide in the code. This consumes resources. Another reason to not use tables until they’re needed: Tables are slow and consume needless bandwidth.) Though it’s not required — you can let your table data cells move like putty based purely on content lengths — you can also define the table’s data cell widths, vertical alignment of text, etc. The rest — fonts, colors, all the style elements which don’t affect the construction (the rendering) of the table — can and should be done in your CSS.

<table width="80%" border="1" cellspacing="0" cellpadding="4" summary="My Plain Table">
<caption>This is an example of a plain HTML table</caption>
<tr><th colspan="2"> This is my plain table </th>  </tr>
<tr><td>Left Cell 1</td><td>Right Cell 1, pertains to Left Cell 1</td></tr>
<tr><td>Left Cell 2</td><td>Right Cell 2, pertains to Left Cell 2</td></tr>
<tr><td>Left Cell 3</td><td>Right Cell 3, pertains to Left Cell 3</td></tr>
<tr><td>Left Cell 4</td><td>Right Cell 4, pertains to Left Cell 4</td></tr>

As written above, it would look like this:

Accessible Smart Tables — Example 1

This is an example of a plain HTML table
This is my plain table
Left Cell 1 Right Cell 1, pertains to Left Cell 1
Left Cell 2 Right Cell 2, pertains to Left Cell 2
Left Cell 3 Right Cell 3, pertains to Left Cell 3
Left Cell 4 Right Cell 4, pertains to Left Cell 4

Now, using a CSS, let’s make the table pretty. There are several ways to do this. This is one.

/* - defines background and border to make it stand out from the page  - */
table {
background : #ccc;
border : 2px solid #666;
margin: auto;
 /* - make the header different from the table; styles the text (optional)  - */
th {
background : #99cc66;
color : #111;
font-size : 110%;
text-align : left;
/* - text-top makes the cell data look better if one cell wraps, this can be in the table itself; styles the text (optional)  - */
td {
vertical-align : text-top;
font-size : 90%;
color : #666;
/* - this is the left cell. there is an easier way to do all this, but this is needed for the smart part  - */
.l {
width : 25%;
text-align : right;
vertical-align : text-top;
font-size : 90%;
background : #99cc66;
font-weight : bold;
color : #111;
padding-left : 6px;
padding-right : 6px;
/* - center-align by default. I like it better this way (optional)  - */
caption  {
text-align : right;
font-size : 90%;
color : #99cc66;
font-style : italic;
margin : auto;

I will now add this style information to my table example. Please note, that for the purpose of this demonstration, being that it’s within this web page, I will add the style information inline so you can see what it looks like. Normally this style information, as shown above, would reside in an external CSS. The rest of the table’s styling, font-family, etc, will be inherited from the style sheet associated with this web log.

Accessible Smart Tables — Example 2

This is an example of a pretty table
This is my pretty table
Left Cell 1 Right Cell 1, pertains to Left Cell 1
Left Cell 2 Right Cell 2, pertains to Left Cell 2
Left Cell 3 Right Cell 3, pertains to Left Cell 3
Left Cell 4 Right Cell 4, pertains to Left Cell 4

Author’s note: Just doing the styles inline like this is a real pain and gives one an acute appreciation for an external style sheet.

So there you have it. Pretty, huh? We’re not done. The table above is quite accessible (and you can resize it and the enclosed text at will, even with Internet Explorer), and it may be pretty, but it can be even more accessible. Moreover, it’s not smart yet. That’s okay, making it smart is next, and it is that action which will increase the accessibility of the table even further by simply making it easier to get to and comprehend the table’s data.

Before I go on, though, you may be wonder just what a “smart table” is, exactly. I will explain. First, what’s the number one issue associated with tables? If you’ve answered this question with something pertaining to focus or finding your place I’d say you’ve hit the nail on the head so to speak. You found the data in a cell in the left column but then you naturally access the data in the cell or cells to the right of it, the ones which share the same table row. It can be easy to lose your place. So, those smudges on your screen, are they from using your finger to help you stay in the same table row?

One way to address this is to add a half-tone, screen, or tint to every other row (or column if your table works that way). This is all fine and good, an easy solution by simple re-classing every other row and style that class with a different background color, and that does make it more accessible. It’s not smart, though. My methods step up the intelligence factor a bit.

I’m going to add some more style information that would normally go on the external CSS. This is what will make the table smart and a lot more accessible. This is what I’m adding:

/* - this color change confirms table focus; crosshair is to make the cursor less obtrusive  - */
table:hover  {
   background : #ccc;
   cursor : crosshair;
/* - this color change confirms table row focus  - */
tr:hover  {
   background : #fafafa;
   color : #000;
/* - but I want to keep the left cell the same (this is really quite optional)  - */
.l:hover  {
   background : #99cc66;

Use this link to see an output example as I can no longer easily output to this page due to the integration complexity.

As you can see from the example, if you have a browser besides Internet Explorer (IE)!, that the table is pretty smart. Focus on the table and the cursor changes to a cross hair. This is done to enhance the focal interaction between the pointing device and the table. Moreover, on hover, the table’s right cell, all table rows, the ones with the long data, changes color subtley. The reason for this is so when you hover over an individual row and the row lights up white (#fafafa;), it stands out from the crowd even further. The text also changes. It’s probably not very noticeable, but the text within the row changes from gray (#666;) to black (#000;).

The left cell, it was decided, shouldn’t change color though it might seem to be beneficial. However, it should be noted, that when that was tried the results were undesirable. There ended up being too much going on. If white was used it seemed too bright. Over-focus if there can be such a thing. The second was to use a subtle variation of the existing color, but that proved too colorful [read: distracting]. The way it is: left cell static; long cell to the right changing, it seems to work best. I’m sure there are color combinations, though, where it would work another way. You could change the text color on hover I suppose. It’s all easy to do. This is a beginning, as always, so build upon this idea and make your own variations and themes.

Okay, now it’s time to make the table smart enough to deal with IE’s short-comings. (Those with IE probably didn’t get too much out of that last Example.)

I’m going to have to use some JavaScript to make the table work on IE browsers. Since the style information, :hover isn’t recognized on anything but an anchor (link or “a”), and since this is a user-side behavior, JavaScript seems to be the only option and thus I’m going to have to create a hover pseudo-class that’s more portable. Portable that is in that I can bring it over into the world of IE.

Here’s the style information I need to add to what we presently have:

/* - this color change confirms table focus; crosshair is to make the cursor less obtrusive  - */
table.hover  {
   background : #99cc66;
   cursor : crosshair;
/* - this color change confirms table row focus - text changes color - */
tr.hover  {
   background : #fafafa;
   color : #000;

It’s not much different than what I wrote before is it? Can you even spot the difference? Looking at the second block of style information I wrote you’ll see, for example table:hover. The difference is it’s now a class. The colon is been replaced by a period “.” (dot) denoting a style class.

This alone will do nothing. What’s needed now is some JavaScript. A function which will switch to a class just for IE. IE can under a class. Here’s the JavaScript you’ll need. Please note the spaces and lack thereof in front between the quote symbol and word hover. First instance, onmouseover, needs the space. The second instance, onmouseout gets no space. Get it wrong and the script won’t work. (Special thanks to “zcorpan” at the Accessify Forum for helping me realize that myself and helping me tweak another script I was working on (form input focus in IE)… it’s sort of how this came to be. I got creative.

/* - this tells the function to run when the page loads  - */
window.onload = function()
/* - this tells the browser to load the new table class from the CSS, namely “.hover” - */
  var table = document.getElementsByTagName("table");
  for(var t = 0; t < table.length; t++){
   table[t].onmouseover = function(){
    this.className += " hover";
   table[t].onmouseout = function(){
    this.className = this.className.replace("hover", "");
/* - same as above, except this gets the class, of the same name, assigned to tr or table row  - */
  var tr = document.getElementsByTagName("tr");
  for(var r = 0; r < tr.length; r++){
   tr[r].onmouseover = function(){
    this.className += " hover";
   tr[r].onmouseout = function(){
    this.className = this.className.replace("hover", "");
// –>

I strongly suggested getting this script off the page and placing a conditional comment on the JavaScript link in all cases of this script’s use. Assuming the file is named “focus_js.js,” getting it off page is easy. Within the <head></head>, write this link:

JavaScript Link

<!--[if IE]><script type="text/JavaScript" src="focus_js.js"></script><![endif]-->

That’s it, for now. Check it out with the new style information added — the pseudo-class .hover added to the table and tr elements .

So, that’s it. What’s above is how I make Accessible Smart Tables. Could they be smarter without being distracting? I’m not sure. I don’t think there is a way around using JavaScript to trick IE. And, as you may have noticed, being that these behaviors are triggered by pointer events, keyboard-only users are left without the features. I suppose, in theory, you could create more JavaScript for both IE and the Gecko-powered browsers, and use focus, then put anchors in the tables. I did try anchors alone and that doesn’t work in anything. I also tried using tabindexes to see if I could get keyboard focus but that, too, failed me.

Perhaps I’ll get some replies here that’ll help take this thing even further than I have already.

Update: This is sort of out of date. The tech is okay, but the colors I used are poor choices.

11 Responses to: “Accessible Smart Tables”

  1. Martin Neczypor responds:
    Posted: July 6th, 2005 at 7:33 am

    Great article, this is very helpful- Since I started right with CSS and HTML I never really knew much about tables, and tried to stay clear of them. Great write-up, very encouraging and informational.

  2. Zach Blume responds:
    Posted: July 8th, 2005 at 11:07 am

    You seem to be on a roll!

  3. Fabian responds:
    Posted: July 12th, 2005 at 2:30 am

    lets not forget a couple more things to make tables more sematic and xhtml friendly
    use the summary for eg.

    also caption helps for the visually impared
    SupaDupa Accessssssibility
    and use the thead and tfoot
    the thead makes a header in the table which is at the top and the tfoot makes a footer at the bottom of the table (the last cell)

    your tables and stuff eg somthing

    footstuff here

    and your content should be in the in the TAG
    for example

    Left Cell 1Right Cell 1, pertains to Left Cell 1
    Left Cell 2Right Cell 2, pertains to Left Cell 2
    Left Cell 3Right Cell 3, pertains to Left Cell 3
    Left Cell 4Right Cell 4, pertains to Left Cell 4

    I will certainly blog this later. other than that good article on the design side of it.

  4. Fabian responds:
    Posted: July 12th, 2005 at 2:32 am

    the code didn’t come up… it should of been the tbody and tfoot and thead example code, it take to long to type out… again.

  5. Bill Woodland responds:
    Posted: September 9th, 2005 at 9:52 am

    Nice article, Mike, and thanks for the IE js, which I’ll be using soon.

    And let’s not forget about the scope parameter in th and td tags. Screen readers use these to help visually impaired people make more sense out of the data. Eg:

    8:00 AMBreakfast
    12:00 PMLunch
    6:00 PMDinner

    Screen readers would speak it like this:

    time 8:00 AM event Breakfast
    time 12:00 PM event Lunch
    time 6:00 PM event Dinner

    Jim Thatcher has a great article that contains better examples than mine.

  6. Bill Woodland responds:
    Posted: September 9th, 2005 at 9:53 am

    oops…the pre tag didn’t work. I intended the html to be visible there.

  7. MIchael Hickland responds:
    Posted: November 25th, 2005 at 6:45 pm

    I love this article and I just had to have a go myself, with anchors of course,

    Cheers :o )


Sorry. Comments are closed.

Note: This is the end of the usable page. The image(s) below are preloaded for performance only.