# Presentation: 529899

## Complicated HTML Tables That Conform to the Section 508 Standards AND Work with Assistive Technology:

- Design Strategies that Work

## Relevant Section 508 Standards

- “Row and column headers shall be identified for data tables.” *1194.22(g)*
- “Markup shall be used to associate data cells and header cells for data tables that have two or more logical levels of rows or column headers.” *1194.22(h)*

## Problem: Complicated Tables

| Stock Prices | Company A |  |  | Company B |  |  |
| --- | --- | --- | --- | --- | --- | --- |
|  | High | Low | Close | High | Low | Close |
| 2001 |  |  |  |  |  |  |
| 	January 1 | 110 | 100 | 107 | 120 | 118 | 118 |
| 	April 15 | 115 | 113 | 113 | 125 | 122 | 124 |
| 2002 |  |  |  |  |  |  |
| 	January 1 | 118 | 115 | 116 | 127 | 126 | 126 |
| 	April 15 | 130 | 128 | 129 | 130 | 129 | 129 |

## Problem: Complicated Tables

| Stock Prices | Company A |  |  | Company B |  |  |
| --- | --- | --- | --- | --- | --- | --- |
|  | High | Low | Close | High | Low | Close |
| 2001 |  |  |  |  |  |  |
| 	January 1 | 110 | 100 | 107 | 120 | 118 | 118 |
| 	April 15 | 115 | 113 | 113 | 125 | 122 | 124 |
| 2002 |  |  |  |  |  |  |
| 	January 1 | 118 | 115 | 116 | 127 | 126 | 126 |
| 	April 15 | 130 | 128 | 129 | 130 | 129 | 129 |

## Terminology: Row Stubs

| Stock Prices | Company A |  |  | Company B |  |  |
| --- | --- | --- | --- | --- | --- | --- |
|  | High | Low | Close | High | Low | Close |
| 2001 |  |  |  |  |  |  |
| 	January 1 | 110 | 100 | 107 | 120 | 118 | 118 |
| 	April 15 | 115 | 113 | 113 | 125 | 122 | 124 |
| 2002 |  |  |  |  |  |  |
| 	January 1 | 118 | 115 | 116 | 127 | 126 | 126 |
| 	April 15 | 130 | 128 | 129 | 130 | 129 | 129 |

- Row Stubs

## Terminology: Nested Row Stubs

| Stock Prices | Company A |  |  | Company B |  |  |
| --- | --- | --- | --- | --- | --- | --- |
|  | High | Low | Close | High | Low | Close |
| 2001 |  |  |  |  |  |  |
| 	January 1 | 110 | 100 | 107 | 120 | 118 | 118 |
| 	April 15 | 115 | 113 | 113 | 125 | 122 | 124 |
| 2002 |  |  |  |  |  |  |
| 	January 1 | 118 | 115 | 116 | 127 | 126 | 126 |
| 	April 15 | 130 | 128 | 129 | 130 | 129 | 129 |

- Nested Row Stubs

## Terminology: Column Headers

| Stock Prices | Company A |  |  | Company B |  |  |
| --- | --- | --- | --- | --- | --- | --- |
|  | High | Low | Close | High | Low | Close |
| 2001 |  |  |  |  |  |  |
| 	January 1 | 110 | 100 | 107 | 120 | 118 | 118 |
| 	April 15 | 115 | 113 | 113 | 125 | 122 | 124 |
| 2002 |  |  |  |  |  |  |
| 	January 1 | 118 | 115 | 116 | 127 | 126 | 126 |
| 	April 15 | 130 | 128 | 129 | 130 | 129 | 129 |

- Column Headers

## Terminology: Nested Column Headers

| Stock Prices | Company A |  |  | Company B |  |  |
| --- | --- | --- | --- | --- | --- | --- |
|  | High | Low | Close | High | Low | Close |
| 2001 |  |  |  |  |  |  |
| 	January 1 | 110 | 100 | 107 | 120 | 118 | 118 |
| 	April 15 | 115 | 113 | 113 | 125 | 122 | 124 |
| 2002 |  |  |  |  |  |  |
| 	January 1 | 118 | 115 | 116 | 127 | 126 | 126 |
| 	April 15 | 130 | 128 | 129 | 130 | 129 | 129 |

- Nested Column Headers

## Terminology: “Diagonal Lookup”

| Stock Prices | Company A |  |  | Company B |  |  |
| --- | --- | --- | --- | --- | --- | --- |
|  | High | Low | Close | High | Low | Close |
| 2001 |  |  |  |  |  |  |
| 	January 1 | 110 | 100 | 107 | 120 | 118 | 118 |
| 	April 15 | 115 | 113 | 113 | 125 | 122 | 124 |
| 2002 |  |  |  |  |  |  |
| 	January 1 | 118 | 115 | 116 | 127 | 126 | 126 |
| 	April 15 | 130 | 128 | 129 | 130 | 129 | 129 |

## Different Types of Tables Tested

- Ordinary rectangular tables
- Nested row stubs only
- Nested column headers only
- Nested row stubs *and* nested column headers

## Techniques Tested

- Table header tags <TH> on column headers and row stubs
- Scope attribute using *COLGROUP*
- Scope attribute without *COLGROUP*
- Header and ID attributes.
- Combinations of all above techniques

## General Conclusions

*Headers / ID* attributes work best.
*Scope= “col”* attribute works fine with basic tables.
- Avoid using *Scope = “colgroup”* attribute.
*<TH> *tags not widely supported except with basic tables.
- Most screen readers let you mix attributes without crashing.

## Example of a Basic Table

| Age | Percentage Poor | Percentage Near Poor |
| --- | --- | --- |
| 65-69 | 8 | 4 |
| 70-74 | 10 | 6 |
| 75-79 | 11 | 7 |
| 80-84 | 12 | 8 |
| 85 and older | 14 | 12 |

## Making Basic Tables Accessible	

- Both *scope attribute* and *<TH>* *tags* make table accessible.
- No need for added complexity of *headers/id* attributes

## Code Snippet of Using Scope Attributes

- <table border="1">
- <tr valign="bottom">
- 	<td>Age</td>
- 	<td align="right" **scope="col“**>Percentage<br>poor</td>
- 	<td align="right" **scope="col“**>Percentage<br>near poor</td>
- </tr>
- <tr>
- 	<td **scope="row“**>65-69</td>
- 	<td align="right">8</td>
- 	<td align="right">4</td>
- </tr>
- ...
- </table>

## Code Snippet Using <TH> Tags

- <table border="1">
- <tr valign="bottom">
- 	<td>Age</td>
- 	**<th align="right">**Percentage<br>poor**</th>**
- 	**<th align="right">**Percentage<br>near poor**</th>**
- </tr>
- <tr>
- 	**<th>**65-69**</th>**
- 	<td align="right">8</td>
- 	<td align="right">4</td>
- </tr>
- ....
- </table>

## Nested Table Headers

| Stock Prices | Company A |  |  | Company B |  |  |
| --- | --- | --- | --- | --- | --- | --- |
|  | High | Low | Close | High | Low | Close |
| January 1, 2002 | 105 | 95 | 102 | 110 | 105 | 107 |
| January 15, 2002 | 110 | 100 | 107 | 120 | 118 | 118 |
| February 1, 2002 | 115 | 113 | 113 | 125 | 122 | 124 |
| February 15, 2002 | 117 | 114 | 115 | 126 | 125 | 125 |
| March 1, 2002 | 118 | 115 | 116 | 127 | 126 | 126 |
| March 15, 2002 | 130 | 128 | 129 | 130 | 129 | 129 |

## Making Nested Column Headers Accessible

- Don’t rely on <TH> tags alone.
- Don’t use *scope = “colgroup”*
- Okay to use *scope = “col”*
- Best to use *headers *and* id *attributes

## Code Snippet Using Headers and ID Attributes

- <table>
- <TR>...<TD **ID=“coA”**>Company A</TD></TR>
- ....
- <TR>...<TD **ID="LowA“**>High</td></tr>
- ...
- <TR>
- <TD **ID="Jan15“**>January 15, 2002</td>
- ....
- <TD **headers="Jan15 coA LowA“**>100</td></tr>
- ....
- </table>

## Nested Row Stubs

| Stock Prices | Company A | Company B |
| --- | --- | --- |
| 2001 |  |  |
| 	January 1 | 100 | 105 |
| 	April 15 | 110 | 107 |
| 2002 |  |  |
| 	January 1 | 115 | 108 |
| 	April 15 | 120 | 115 |

## Making Nested Row Stubs Accessible

- Use *headers* and *id *attributes to make tables accessible.
- Okay to mix *headers* and *id* attributes in the same cell.
*Scope = “col”* can be used in column headers.
- <TH> tags are handled unreliably by some screen readers.

## Code Snippet Using Headers/ID in a Nested Row Stub

- <table>
- <TR>...<TD **ID=“coA”**>Company A</TD></TR>
- ....
- <TR>...<TD **ID="2001“**>2001</td></tr>
- ...
- <TR>
- <TD **ID="Apr152001" HEADERS="2001“**>April 15, 2001</td>
- ....
- <TD **HEADERS="coA 2001 Apr152001“**>110</td></tr>
- ....
- </table>

## Nested Row Stubs AND Nested Column Headers

| Stock Prices | Company A |  |  | Company B |  |  |
| --- | --- | --- | --- | --- | --- | --- |
|  | High | Low | Close | High | Low | Close |
| 2001 |  |  |  |  |  |  |
| 	January 1 | 110 | 100 | 107 | 120 | 118 | 118 |
| 	April 15 | 115 | 113 | 113 | 125 | 122 | 124 |
| 2002 |  |  |  |  |  |  |
| 	January 1 | 118 | 115 | 116 | 127 | 126 | 126 |
| 	April 15 | 130 | 128 | 129 | 130 | 129 | 129 |

## Making Complicated Tables Accessible

- Do not rely on <TH> tags for non-diagonal associations.
- Don’t use *scope = “colgroup”*.
- Try to use *headers* and *id* attributes.
- Try to simplify tables, where possible.
- Code snippets same as before.

## Other Points

- Pad cells with blank spaces--- try not to use blank columns.
- Try to avoid blank rows.
- Try to avoid blank columns or using columns just for formatting spacing.
- Try to avoid blank cells where possible.
- Try to simplify table structure.
- Use anchor tags for footnotes.