Row and column headers
Row and column headers should be identified for data tables.
Tables used strictly for layout purposes should not have header rows or columns. Data tables should have column and row headers appropriately identified (using the <TH> tag)
Tables allow us to arrange data -- text, images, links, other tables, etc. -- into rows and columns of cells. Tables should not be used purely as a means to layout document content as this may present problems when rendering to non-visual media. Additionally, when used with graphics, these tables may force users to scroll horizontally to view a table designed on a system with a larger display. To minimize these problems, authors should use style sheets, not tables, to control layout.
Table cells may either contain "header" information (use the TH element) or "data" (see the TD element). Cells may span multiple rows and columns. Individual cells can be labeled to communicate heading information about the cell (see markup for cells in data tables below). This information greatly assists users with visual disabilities, and allows multi-modal wireless /preowsers with limited display capabilities (e.g., Web-enabled pagers and phones) to handle tables.
Each table may have an associated caption that provides a short description of the table's purpose: e.g., <CAPTION>text</CAPTION>. For a longer description, use the summary attribute of the Table Element: e.g.,<TABLE summary="text">
When using Dreamweaver, you can select Edit>Preferences>Accessibility and then choose the tables checkbox. When you create a table, the following dialog box will appear:

This dialog box includes caption and summary text input fields. It also allows you to automatically create header tags for all your rows and/or columns. The align attribute of the caption element, meanwhile, like all style related attributes, can be more efficiently set in a style sheet.
For more information, see the World Wide Web Consortium's table page, from which this explanation has been adapted. For a /preief example, see the table below:
<TABLE border="1" summary="This table charts the number of cups of coffee consumed by each senator, the type of coffee (decaf or regular), and whether taken with sugar."> <caption>Cups of coffee consumed by each senator</caption> <tr> <th>Name</th> <th>Cups</th> <th>Type of Coffee</th> <th>Sugar?</th> </tr> <tr> <th>T. Sexton</th> <td>10</td> <td>Espresso</td> <td>No</td> </tr> <tr> <th>J. Dinnen</th> <td>5</td> <td>Decaf</td> <td>Yes</td> </tr> </table>
| Name | Cups | Type of Coffee | Sugar? |
|---|---|---|---|
| T. Sexton | 10 | Espresso | No |
| J. Dinnen | 5 | Decaf | Yes |
Markup for cells in data tables
Markup (html tags) should be used to associate data cells and header cells for data tables that have two or more logical levels of row or column headers
Table cells should be associated with the appropriate headers (i.e. with the id, headers, scope and/or axis HTML attributes
- Headers (THEAD, TFOOT, and TBODY)
- Scope
- Axis
Headers
Use headers to identify relationships among table cells. Headers allow screen readers to interpret the information in tables. If there is more than one row or column of headers, a more extensive description of the relationship between cells helps the user understand the table's structure better.
Table rows may be grouped into head, foot, and body sections, with the THEAD, TFOOT and TBODY elements, respectively. These row groups convey additional structural information and may be rendered in ways that emphasize this structure. The head/body/foot division can help users scroll sections independently of the head and foot. When long tables are printed, the head and foot information may be repeated on each page that contains table data.
The table head and table foot should contain information about the table's columns. The table body should contain rows of table data. The following example illustrates the order and structure of table heads, feet, and bodies.
<TABLE> <THEAD> <TR> ...header information... </THEAD> <TFOOT> <TR> ...footer information... </TFOOT> <TBODY> <TR> ...first row of block one data... <TR> ...second row of block one data... </TBODY> <TBODY> <TR> ...first row of block two data... <TR> ...second row of block two data... <TR> ...third row of block two data... </TBODY> </TABLE>
TFOOT must appear before TBODY within a TABLE definition.
Column groups can also provide additional structural information. Use the COLGROUP and COL elements to declare column properties at the start of a table definition. Users can then read the table incrementally rather than having to wait for all the table data to arrive.
Scope
The following example associates header and data information with the "scope" attribute rather than headers. Scope must have one of the following values: "row", "col", "rowgroup", or "colgroup." Scope specifies the set of data cells to be associated with the current header cell. This method is particularly useful for simple tables like the following:
| Name | Cups | Type of Coffee | Sugar? |
|---|---|---|---|
| T. Sexton | 10 | Espresso | No |
| J. Dinnen | 5 | Decaf | Yes |
Here is the HTML for the above table. Note the <TH> tags defining each column.
<TABLE border="border" summary="This table charts the number of cups of coffee consumed by each senator, the type of coffee (decaf or regular), and whether taken with sugar."> <CAPTION>Cups of coffee consumed by each senator</CAPTION> <TR> <TH scope="col">Name</TH> <TH scope="col">Cups</TH> <TH scope="col" ab/pre="Type">Type of Coffee</TH> <TH scope="col">Sugar?</TH> </TR> <TR> <TH scope="row">T. Sexton</TH> <TD>10</TD> <TD>Espresso</TD> <TD>No</TD> </TR> <TR> <TH scope="row">J. Dinnen</TH> <TD>5</TD> <TD>Decaf</TD> <TD>Yes</TD> </TR> </TABLE>
The axis tag can be used to create categories in more complex tables. Use it to group similar elements.
| Meals | Hotels | Transport | subtotals | |
|---|---|---|---|---|
| San Jose | ||||
| 25-Aug-97 | 37.74 | 112.00 | 45.00 | |
| 26-Aug-97 | 27.28 | 112.00 | 45.00 | |
| subtotals | 65.02 | 224.00 | 90.00 | 379.02 |
| Seattle | ||||
| 27-Aug-97 | 96.25 | 109.00 | 36.00 | |
| 28-Aug-97 | 35.00 | 109.00 | 36.00 | |
| subtotals | 131.25 | 218.00 | 72.00 | 421.25 |
| Totals | 196.27 | 442.00 | 162.00 | 800.27 |
A speech synthesizer might render the example above by speaking the following:
San Jose 25-Aug-97: Meals: 37.74, Hotels: 112.00, Transport: 45.00 26-Aug-97: Meals: 27.28, Hotels: 112.00, Transport: 45.00 subtotals: Meals: 65.02, Hotels: 224.00, Transport: 90.00, subtotals: 379.02 etc.
Alternatively, the user may be interested only in a particular column, and with the appropriate markup can instruct the speech synthesizer to read it as follows:
Meals San Jose 25-Aug-97: 37.74 26-Aug-97: 27.28 subtotals: 65.02 Seattle 27-Aug-97: 96.25 28-Aug-97: 35.00 subtotals: 131.25 Totals: 196.24
The HTML source for this example follows. Notice how "axis", "headers", and "id" attributes are used in some of the TH and/or TD tags. The axis attribute creates categories of headers uniquely identified by the id attribute, and the headers attribute refers to all of the headers associated with a particular cell.
<TABLE border="border" summary="this complex table example summarizes travel expenses incurred during August trips to San Jose and Seattle"> <CAPTION> Travel Expense Report </CAPTION> <TR> <TH></TH> <TH id="e1" axis="expenses">Meals</TH> <TH id="e2" axis="expenses">Hotels</TH> <TH id="e3" axis="expenses">Transport</TH> <TH id="s1" axis="subtotals">subtotals</TH> </TR> <TR> <TH id="l1" axis="location">San Jose</TH> </TR> <TR> <TD id="d1" axis="date">25-Aug-97</TD> <TD headers="l1 d1 e1">37.74</TD> <TD headers="l1 d1 e2">112.00</TD> <TD headers="l1 d1 e3">45.00</TD> <TD></TD> </TR> <TR> <TD headers="l1" id="d2" axis="date">26-Aug-97</TD> <TD headers="l1 d2 e1">27.28</TD> <TD headers="l1 d2 e2">112.00</TD> <TD headers="l1 d2 e3">45.00</TD> <TD></TD> </TR> <TR> <TH headers="l1"id="s2"axis="subtotals">subtotals</TH> <TD headers="l1 s2 e1">65.02</TD> <TD headers="l1 s2 e2">224.00</TD> <TD headers="l1 s2 e3">90.00</TD> <TD headers="l1 s2 s1">379.02</TD> </TR> <TR> <TH id="l2" axis="location">Seattle</TH> </TR> <TR> <TD headers="l2"id="d3" axis="date">27-Aug-97</TD> <TD headers="l2 d3 e1">96.25</TD> <TD headers="l2 d3 e2">109.00</TD> <TD headers="l2 d3 e3">36.00</TD> <TD></TD> </TR> <TR> <TD headers="l2"id="d4" axis="date">28-Aug-97</TD> <TD headers="l2 d4 e1">35.00</TD> <TD headers="l2 d4 e2">109.00</TD> <TD headers="l2 d4 e3">36.00</TD> <TD></TD> </TR> <TR> <TD headers="l2"id="s3" axis="subtotals">subtotals</TD> <TD headers="l2 s3 e1">131.25</TD> <TD headers="l2 s3 e2">218.00 </TD> <TD headers="l2 s3 e3">72.00</TD> <TD headers="l2 s3 s1">421.25</TD> </TR> <TR> <TH id="t1" axis="totals">Totals</TH> <TD headers="t1 e1">196.27</TD> <TD headers="t1 e2">442.00</TD> <TD headers="t1 e3">162.00</TD> <TD headers="t1 s1">800.27</TD> </TR> </TABLE>
For more information, see the World Wide Web Consortium's table page, from which this explanation has been adapted.