Watch our 3-minute video to find out how you can learn Web Accessibility with a live instructor.
Additional Resources

Accessible Tables

In this lesson of the Accessibility tutorial, you will learn...
  1. About HTML tables.
  2. How to create accessible tables.

Table Basics

HTML tables on the web come in two varieties, layout tables and data tables.

There is no question that the vast majority of tables on the web are layout tables, used to structure the visual appearance of the page. Often the structure of tables is remarkably complex, with tables nested in tables as much as seven deep.

In the Navigation lesson we talked a little bit about how tables are read, or linearized, independently of how complex those tables are. At least the definition of the linearization algorithm is simple. Lay out the text a line at a time starting with the first cell of the first row; then move across the columns of the first row, then proceed to the second row, and so on. If you come to a table in that process, linearize it and then continue. Another description of linearzation is "source code order." If you look at the source code of a page, and remove all the table tags (<table>, <tr>, <td> <th>, etc.) then the resulting text is the linearized version of the table. Finally, if you want an easy technique to see the way tables are spoken, look at a site that uses tables for layout, and apply the Linearize function in the Tables menu of the web Accessibility Toolbar.

You should make sure that your pages make sense when linearized in this fashion. As we discussed earlier, one of the simplest views of your page in linear form is provided by the "Lynx view," a rendering of the page as if you were using the Lynx text browser. The Delorie software Lynx Viewer site provides you the opportunity of seeing your page as if the browser were Lynx. Or you can use the Web Accessibility Toolbar, Check > Lynx Viewer. Usually the page will make sense.

Unless, that is, one or more of your tables is really a data table, because, while layout tables usually linearize well, data tables do not.

So what are data tables? How are they distinguished from layout tables? Data tables present things like financial results, rainfall totals by city and month, TV listings or bus schedules. What do these have in common? What is common is that the meaning of data in most cells of the table depends on heading information, which is usually in the first row and the first column of the table. You cannot know what the data means unless you are aware of the contents of the corresponding headings.

For layout tables, information in various cells stands on its own. There are no headings - just table cells containing text and images. In contrast, headings are crucially important for understanding (or reading) data tables. That is the problem! Your tables must be designed and marked up in such a way as to ensure that assistive technology will know where the headings are and be able to announce them.

Think of a TV listing -- for example, TV Guide: Screen Shot of TV listings

Here is part of the text view of this table from IBM Home Page Reader, starting at the time indicator (and Heading), 7:30:

7:30 PM
8:00 PM
8:30 PM
2 KTBC
American Juniors
Paradise Hotel
3 KVUE
George Lopez (Repeat)
Drew Carey
Drew Carey
Dating Experiment>
4 KXAN
<Fame
Law & Order (Repeat)
5 KEYE
<60 Minutes II
Perfect Murder, Perfect Town (Repeat)
6 INFO
<Information Channel
Information Channel
8 HSN
<24 Hour Jewelry Celebration
24 Hour Jewelry Celebration
9 KLRU
<Ken Burns American Stories (Repeat)
West Point (Repeat)
10 TBN
International Intelligence Briefing
Gaither Homecoming
Jack Van Impe Presents

When you read this, you will find that important information, represented by the tabular structure, is lost. Because of spanned cells, there is no way to even guess the time slot for a program, even if you did remember the headings. Imagine searching for a program title and then trying to figure out at what time and on what channel it will be aired. Nearly impossible!

This financial data table from Fidelity.com has similar problems. Just imagine starting to read this table in the middle. It is hard enough to remember the column headings, let alone keep track of them as you view numeric data one cell at a time.

Remember that visually you can quickly glance at row and column headers to understand a piece of data; you can't do that when you are reading the table linearly. screenshot of financial table

There are a number of constructs in HTML 4.0 that contribute to making data tables accessible, that contribute to making it possible to listen to and understand a table. These are thoroughly discussed in the Tables section of the HTML 4.0 document.

We will discuss the three most important techniques for giving assistance to those with disabilities who are trying to interpret tabular information.

Using the caption Element and the summary Attribute

If you can see a web page and you come across a data table, you naturally and automatically scan that table to get a quick sense of what the table presents. But some users have difficulty making that analysis, or simply cannot because they listen to the contents of the display rather than look at it. There are two techniques to help those users.

The caption element provides the web developer with a standard way of programmatically associating the title of the table with the table itself. The caption can appear at the top or bottom of the table. Even such a simple label can help orient a user to table content. And having it programmatically attached to the table means that screen readers will announce that as the table is encountered. Table with caption

The simple table above has a caption, "Today's Lunch Menu," which explains the table contents. After hearing this caption, reading the three heading cells and three data cells would make (more) sense.

The following is the code for that table. Note the caption element directly after the table element. To move the caption to the bottom of the table, place the caption element just before the end table tag (</table>).

Code Sample: AccessibleTables/Demos/Code01.xml

<table border="1" cellpadding="0" >
 <caption>Today's Lunch Menu</caption>
 <tr>
  <th>Salad</th>
  <th>Entree</th>
  <th>Dessert</th>
 </tr>
 <tr>
  <td>Caesar </td>
  <td>Chicken Divan</td>
  <td>Chocolate Mousse</td>
 </tr>
</table>

Because we know how assistive technology reads a table, we also know that this table would be organized better with its headings down a column, like this: Table with headings in first column The code is shown below:

Code Sample: AccessibleTables/Demos/Code02.xml

<table border="1" cellpadding="3">
 <caption><p>Today's Lunch Menu</p></caption>
 <tbody>
  <tr>
   <th>Salad</th>
   <td>Caesar</td>
  </tr>
  <tr>
   <th>Entree</th>
   <td>Chicken Divan</td>
  </tr>
  <tr>
   <th>Dessert</th>
   <td>Chocolate Mousse</td>
  </tr>
 </tbody>
</table>

Written this way, the lunch menu would read naturally (thanks to Home Page Reader):

Today's Lunch Menu
Salad Caesar
Entree Chicken Divan
Dessert Chocolate Mousse

When a table is more complicated, web authors are encouraged to use the summary attribute of the table element. This, like the longdesc attribute for images, is not represented visually. It is rendered from the HTML code by assistive technology like screen readers and talking browsers.

The summary attribute should contain a summary of the way the table is laid out - not a summary of the results. It should provide an orientation for someone who listens to the table.

Code Sample: AccessibleTables/Demos/Summary.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Table with Summary</title>
</head>

<body>
<table border="1" summary="This table of Oceana Airlines dinner service lists the five dinner courses (column headings) for each class of service, Economy, Business, and First (row headings)" cellpadding="3">
 <caption>Oceana Airlines Dinner Service</caption>
---- Code Omitted ----

Oceana Airlines dinner service

For this Dinner Service table the table element with its summary attribute looks like this.

Code Sample: AccessibleTables/Demos/Code03.xml

<table border=1
summary="This table of Oceana Airlines dinner service gives
 the five dinner courses (column headings)
 for each class of service, Economy, Business, and First (row headings)">

With that summary, a person who is using a screen reader will have an overview of the table layout before he starts to read it.

Using Column and Row Headers

The techniques for dealing with data tables that we discussed so far are designed to give an overview of the table. These are not required by the Section 508 Standards. The next two techniques deal with the internals of the table. These techniques will enable you to satisfy the following two Section 508 Standards:

Row and column headers shall be identified for data tables.

Markup shall be used to associate data cells and header cells for data tables that have two or more logical levels of row or column headers.

Let's look first at 1194.22(g) that requires that you, in effect, label table headers as html headers (th), not unlike what we talked about in the Navigation lesson where heading text should be marked up as HTML headings (h1, h2, etc).

Each table cell is either a pure data cell (td) or a header cell (th). By default, headers will appear centered in bold so that most users can easily identify them. If this is not exactly the way you want your headers to appear, you can modify their appearance using style sheets. By labeling a cell as a th, you are identifying it as a table header as required by ยง1194.22 (g).

In addition to making the headers stand out, they can be identified by assistive technology so that when a talking browser is reading a specific cell it can, on command, search for the header cells and announce them. In addition, as the user moves from cell to cell, the assistive technology will announce the row and column headers that have changed. For example, moving across the Business class row in the Oceana Airlines Dinner Service table above, a screen reader user would hear, "Appetizer, Shrimp Cocktail, Salad, Mixed Greens, Wine, Oceana Label Cardonnay or Merlot, Entree, Chicken Satay or Beef Tips, Desert New York Style Cheesecake."

Both the Lunch Menu table and the Oceana Dinner Service table above have headers specified as they should be. You can see those headers (th) in the HTML code for the Lunch Menu Table. You can also use the Web Accessibility Toolbar, Tables > Table headers; this will put a black background on all cells which are table header cells (th).

The Oceana Dinner Service table is a little different because of the ambiguity of whether the top left cell is a header for its column or its row. This is resolved using the scope attribute on that th cell, or, as is recommended by many, on every th cell. The possibilities are scope="col" (which is appropriate for that top left cell) or scope="row". Here is the code for the first two rows of the Dinner Service table.

Code Sample: AccessibleTables/Demos/Code04.xml

<tr>
<th scope="col">Class of Service</th>
<th>Appetizer</th>
<th>Salad</th>
<th>Wine</th>
<th>Entree</th>
<th>Dessert</th>
</tr>
<tr>
<th>Economy</th>
<td>Peanuts</td>
<td>None</td>
<td>Complimentary Soft Drinks, Liquor for Purchase</td>
<td>Ham and Cheese Sandwich</td>
<td>Packaged Cookies</td>
</tr>

The coding for this table has evolved since it first appeared in Mike Paciello's book (Paciello, Michael G., Web Accessibility for People with Disabilities, Lawrence, Kansas: CMP Books, 2000); Mike used headers/id markup (more about that later) which is not necessary. The earlier version of this course included the scope attribute on all cells, not just the one cell whose scope is ambiguous. When you are using th cells, assistive technology knows they are headers and can deduce the scope; so the extra scope attributes are not necessary.

With the table marked up this way, a screen reader would announce the cells in the second row something like this: "Appetizer, Peanuts; Salad, None;" etc.

Alternative to using header cells (th) with the scope to resolve ambiguity, you can use data cells (td) with the scope attribute on any cell that is a heading. This technique has the advantage that you don't have to go back and restyle the heading text. Any cell is a heading if it is a th or it is a td with a scope attribute.

Using the headers Attribute

The final technique for making tables accessible is the most rigorous and programmatic. HTML 4.0 introduced the headers attribute for table cells. With the headers attribute you can specify any other cell or cells as the heading information for a given (data) cell.

The idea is simple. You attach an id attribute to any cell you want to be a header cell. Then, add the id's of each header cell to the headers attribute of a data cell.

For a simple case, let's say the id's of the column headers are c1, c2, c3, and c4 and the id's of the row headers are r1, r2, r3, and r4. Then the cell at row 3, column 2 would have headers="r3 c2" or the other way around, headers="c2 r3" if that sounded better.

In the "rectangular examples" above, assistive technology can figure out which is the header information. But in a table like the Travel Expense Report that follows, that is nearly impossible. (This table is from the Web Accessibility Initiative, Techniques for Web Content Accessibility Guidelines 1.0. Tables are discussed in Section 5 of that techniques document.)

Table commented out below. Need screenshot.

Here is sample HTML mark up for the data cells of this table using the headers attribute. I have used the convention that c1, c2, c3, ... are the id's of the column headings and r1, r2, r3, ... are the id's of the row headings.

Code Sample: AccessibleTables/Demos/Code05.xml

<table border="1">
 <caption>Travel Expense Report</caption>
 <tr>
  <td></td>
  <th id="c2">Meals</th>
  <th id="c3">Hotels</th>
  <th id="c4">Transport</th>
  <td id="c5">subtotals</td>
 </tr>
 <tr>
  <th id="r2">San Jose</th>
  <td></td>
  <td></td>
  <td></td>
  <td></td>
 </tr>
 <tr>
  <td id="r3" >25-Aug-97</td>
 <td headers="c2 r2 r3" bgcolor="#ffff00">37.74</td>
 <td headers="c3 r2 r3">112.00</td>
 <td headers="c4 r2 r3">45.00</td>
 <td></td>
 </tr>
 <tr>
  <td id="r4">26-Aug-97
  <td headers="c2 r2 r4">27.28</td>
  <td headers="c3 r2 r4">112.00</td>
  <td headers="c4 r2 r4">45.00</td>
 ...
 <tr>
  <th id="r10">Totals</th>
  <td headers="c2 r10">196.27</td>
  <td headers="c3 r10">442.00</td>
  <td headers="c4 r10">162.00</td>
  <td headers="c5 r10">800.27</td>
 </tr>
</table>

The highlighted cell with the value 37.74, for example, is associated with the date "25-Aug-97" (id="r3"), the city "San Jose," (id="r2") and expense item "Meals" (id="c2"). To make it readable, the subject cell is coded:

<td headers="c2 r2 r3">37.74</td>

Assistive technology might then read this cell "Meals, San Jose, 25-Aug-97, 37.74" or "37.74, Meals, San Jose, 25-Aug-97."

Exercise: Accessible Tables

Duration: 15 to 30 minutes.

In this exercise, you will create an accessible table.

  1. Open the file /AccessibleTable/Exercises/exercise1.htm.
  2. Linearize the table either by removing the code or by using the Linearize feature on the Web Accessibility Toolbar.
  3. Save the results in a text file or word document.
  4. Correct the code in exercise1.htm to increase the table's accessibility.
  5. Repeat the linearization process and compare with the previous results. Which table is easier to understand when linearized?
  6. Compare with the file /AccessibleTable/Solutions/solution1.htm.

Exercise: Accessible Complex Table

Duration: 15 to 30 minutes.

In this exercise, you will create an accessible complex table.

  1. Open the file /AccessibleTable/Exercises/exercise2.htm.
  2. Linearize the table either by removing the code or by using the Linearize feature on the Web Accessibility Toolbar.
  3. Save the results in a text file or word document.
  4. Correct the code in exercise2.htm to increase the table's accessibility.
  5. Repeat the linearization process and compare with the previous results. Which table is easier to understand when linearized?
  6. Compare with the file /AccessibleTable/Solutions/solution2.htm.

Accessible Tables Conclusion

In terms of money and workload, implementing accessible tables can be an expensive proposition. That expense can be reduced with careful design of data tables. If a table with 10 rows and 10 columns requires headers/id markup, then all 100 cells must be specially coded. For simple tables, about 18 cells need special attention and what is done is repetitive, which it is not true for the headers/id case.

Here is a summary of the techniques for accessible tables:

  • Use caption element as a title for the data table and/or use the summary attribute to give a brief overview of the structure of the table.
  • Markup all table header cells
    • Use the table header element, th, for all header cells and add the scope attribute when that scope is ambiguous (corners).
    • Or use td together with the scope to specify header cells
    • Or use id attributes on the header cells and the headers attribute on the data cells to explicitly associate header information with data cells. This is essential if there are data cells whose header information is not in the same row and the same column as that cell.
  • Do not use any of the accessible data table markup (th, scope, headers, caption or summary) on a table used for layout. In particular, avoid gratuitous announcements resulting from summary="This table used for layout".
To continue to learn Accessibility go to the top of this page and click on the next lesson in this Accessibility Tutorial's Table of Contents.

Use of http://www.web-accessibility-tutorial.com (Website) implies agreement to the following:

Copyright Information

All pages and graphics on Website are the property of Webucator, Inc. unless otherwise specified.

None of the content on Website may be redistributed or reproduced in any way, shape, or form without written permission from Webucator, Inc.

No Printing or saving of pages or content on Website

This content may not be printed or saved. It is for online use only.


Linking to Website

You may link to any of the pages on Website; however, you may not include the content in a frame or iframe without written permission from Webucator, Inc.


Warranties

Website is provided without warranty of any kind. There are no guarantees that use of the site will not be subject to interruptions. All direct or indirect risk related to use of the site is borne entirely by the user. All code and explanations provided on this site are provided without warranties to correctness, performance, fitness, merchantability, and/or any other warranty (whether expressed or implied).


For individual private use only

You agree not to use this online manual to deliver or receive training. If you are delivering or attending a class that is making use of this online manual, you are in violation of our terms of service. Please report any abuse to courseware@webucator.com. If you would like to deliver or receive training using this manual, please fill out the form at http://www.webucator.com/Contact.cfm