Bellevue College

Web Publishing Guide

Website Tips

There are lots of bright ideas out there. These will make your website better and your job easier.

light bulb

Tables and Accessibility

There are two types of tables, layout tables and data tables. Layout tables are used to visually organize content on a website and data tables are used to present data so column information is related to row information. Keep reading to find out more about accessibility techniques for all types of tables.

Layout Table Accessibility

Layout tables are sometimes used to organize the design and content of websites. In years past, many websites used tables for layout purposes.

The use of tables for layout is no longer good practice and in many ways impedes access for people with disabilities. So...don't use tables for layout!

Data Table Accessibility

Data tables organize data into a chart or spreadsheet in rows and columns. A data table is different from a layout table in that the column information presented is related to the row information.

When it comes to making data tables accessible, there are two types of data tables: simple and complex. A simple data table has up to one row of column headers and up to one column of row headers. A complex data table has two or more logical levels of row or column headers. Simple data tables are easily made accessible. Because of this it is usually a good idea to simplify your tables when possible.

Example of a simple data table

Name Phone Number Age Weight
Steve Nelson 425/555-2186 54 130 lbs.
Maria Sanchez 425/555-8741 43 120 lbs.

( Notice how the above table only has table headers on the top row.)

 

Example of a complex data table

Travel Expense Report
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

(Notice how the above table has multiple levels of column headers.)

 

Building Simple Data Tables

To make a simple data table accessible you need to make sure that table headers use a table header tag (<th>) on all headers. Most WYSIWYG (what you see is what you get) HTML applications should allow you to easly turm a table cell into a table header cell.

Example

Name Phone Number Age Weight
Steve Nelson 425/555-2186 54 130 lbs.
Maria Sanchez 425/555-8741 43 120 lbs.

 

View HTML code

<table width="80%" border="1" cellspacing="1"  cellpadding="2">    <tr>   <th>Name</th>  <th>Phone Number</th>  <th>Age</th>  <th>Weight</th>  </tr>  <tr>   <td>Steve Nelson</td>  <td>425/555-2186</td>  <td>54</td>  <td>130 lbs.</td>  </tr>  <tr>   <td>Maria Sanchez</td>  <td>425/555-8741</td>  <td>43</td>  <td>120 lbs.</td>  </tr>  </table>

Notice how the table cells for the top row use the <th> tag instead of the <td> tag. This tells browsers that the contents of those table cells are table headers. In the above example it is acceptable to make the entire left column of table cells as table headers.

Building Complex Data Tables

Complex data tables are a little more cumbersome to make accessible and in most cases you will need to modify the HTML code to make these tables accessible. Like simple data tables, you still need to mark all table headers using the <th> tag. Since complex data tables have multiple levels of logical row or column headers, you need to use other HTML tags and attributes to associate table data with the different levels of table headers. There are multiple methods you can use to make complex data tables accessible, but this will depend on the data table or your personal preference.

HTML allows various ways to associate table content.

 

Using the scope attribute

One of the easiest ways of making your table accessible is through the use of the scope atribute. The scope attribute can associate rows, columns, row groups and column groups to a table cell.

The scope attribute can have four different values: "row", "col", "rowgroup" or "colgroup." By applying the value of 'row' to the scope attribute in a table header you associate all table cells in that row to the particular table header. By applying the value of 'col' to the scope attribute in a table header you associate all table cells in that column to the particular table header. On the table below you will notice how the scope attribute associate table cells to 2 different levels of column headers.

Example table using scope="col"

  Winter Summer
  Morning Afternoon Morning Afternoon
Wilma 9-11 12-6 7-11 12-3
Fred 10-11 12-6 9-11 12-5

 

View HTML code

<table>  <tr>  <th>&nbsp;</th>  <th colspan="2" scope="col" >Winter</th>  <th colspan="2" scope="col" >Summer</th>  </tr>    <tr>  <th>&nbsp;</th>  <th scope="col" >Morning</th>  <th scope="col" >Afternoon</th>  <th scope="col" >Morning</th>  <th scope="col" >Afternoon</th>  </tr>    <tr>  <td scope="row" >Wilma</td>  <td>9-11</td>  <td>12-6</td>  <td>7-11</td>  <td>12-3</td>  </tr>    <tr>  <td scope="row" >Fred</td>  <td>10-11</td>  <td>12-6</td>  <td>9-11</td>  <td>12-5</td>  </tr>    </table>

 

Scope vs. Headers and ID attributes

It is much easier to establish relationships between table cells and headers using the scope attribute.

Example of table using Scope attribute

Name Cups Type of Coffee Sugar?
T. Sexton 10 Espresso No
J. Dinnen 5 Decaf Yes

 

View HTML code

<table border="1" summary="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.">    <tr>  <th scope="col">Name</th>  <th scope="col">Cups</th>  <th scope="col" abbr="type">Type of Coffee</th>  <th scope="col">Sugar?</th>    <tr>  <td>T. Sexton</td>  <td>10</td>  <td>Espresso</td>  <td>No</td>    <tr>  <td>J. Dinnen</td>  <td>5</td>  <td>Decaf</td>  <td>Yes</td>    </table> 

 

Example of same table using headers and id attributes

Name Cups Type of Coffee Sugar?
T. Sexton 10 Espresso No
J. Dinnen 5 Decaf Yes

 

View HTML code

<table border="1" summary="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.">    <tr>  <th id="t1">Name</th>  <th id="t2">Cups</th>  <th id="t3" abbr="Type">Type of Coffee</th>  <th id="t4">Sugar?</th>  </tr>    <tr>  <td headers="t1">T. Sexton</td>  <td headers="t2">10</td>  <td headers="t3">Espresso</td>  <td headers="t4">No</td>  </tr>    <tr>  <td headers="t1">J. Dinnen</td>  <td headers="t2">5</td>  <td headers="t3">Decaf</td>  <td headers="t4">Yes</td>  </tr>    </table>

A speech synthesizer might render thesw table as follows

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.
Name: T. Sexton, Cups: 10, Type: Espresso, Sugar: No
Name: J. Dinnen, Cups: 5, Type: Decaf, Sugar: Yes

Note: how the header "Type of Coffee" is abbreviated to "Type" using the abbr attribute.

 

Using Axis for far more complicated tables

To create complex relationships between table cells, you will need to use the axis attribute along with the headers and id attributes

Example

Travel Expense Report
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

 

View HTML code

<table border="1">    <caption>  Travel Expense Report   </caption>    <tr>  <th>  <th id="header2" axis="expenses">Meals   <th id="header3" axis="expenses">Hotels   <th id="header4" axis="expenses">Transport   <td>subtotals</td>    <tr>  <th id="header6" axis="location">San Jose   <th>  <th>  <th>  <td>    <tr>  <td id="header7" axis="date">25-Aug-97   <td headers="header6 header7 header2">37.74   <td headers="header6 header7 header3">112.00   <td headers="header6 header7 header4">45.00   <td>      <tr>   <td id="header8" axis="date">26-Aug-97   <td headers="header6 header8 header2">27.28   <td headers="header6 header8 header3">112.00   <td headers="header6 header8 header4">45.00   <td>              <tr>   <td>subtotals   <td>65.02</td>  <td>224.00   <td>90.00   <td>379.02              <tr>   <th id="header10" axis="location">Seattle   <th>   <th>   <th>   <td>              <tr>   <td id="header11" axis="date">27-Aug-97   <td headers="header10 header11 header2">96.25   <td headers="header10 header11 header3">109.00   <td headers="header10 header11 header4">36.00   <td>              <tr>   <td id="header12" axis="date">28-Aug-97   <td headers="header10 header12 header2">35.00   <td headers="header10 header12 header3">109.00   <td headers="header10 header12 header4">36.00   <td>              <tr>   <td>subtotals   <td>131.25   <td>218.00   <td>72.00   <td>421.25              <tr>   <th>Totals   <td>196.27   <td>442.00   <td>162.00   <td>800.27              </table>

A speech synthesizer might render it this table 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

More resources on data tables