Tables, data and information: accessibility for developers

  • Author: Access iQ ®
  • Date: 1 Feb 2013
  • Access: Premium

Quick facts

In order to have accessible table data it is important that the table is not too complex, uses elements that help identify and describe the headers and other descriptive content, parses successfully and presents to the person with disabilities a similar way to a person without disabilities.


  • Avoid complex tables
  • Do not use tables for layout
  • Provide captions and summaries for tables
  • Use header and id attributes to describe table content
  • Use tables to lay out forms

Tables are one of the best ways to organise a grid of information, or present information in a way that helps show relationships between data elements over time or between sources.

In the past, HTML tables were used to layout page elements before HTML markup matured to the stage it is now and CSS was not advanced enough to present visual element with the precision designers expected.

There is no longer any need to use tables for page layout and doing so will make accessibility much harder to achieve when tables are used for non-tabular data. In addition, using tables for layout is now inferior to using CSS/HTML as their rigidity cannot compete with the fluid grace, flexibility, adaptability and functionality of CSS.

Screen readers will read content as if there were no HTML at all so it is important to remember several points. Screen readers do not work well with rowspan and colspan attributes and read row by row, from left to right. Thus, the following table will be read by a screen reader as: "one, four, three, two", since it will linearise the text according to the rules of reading a table.

Example 1:

A table with four columns and three rows. The text "one" is in row 1, column 1; the text "two" is in row 3, column 2; the text "three" is in row 2, column 3; and the text "four" is in row 1, column 4.

For these reasons, and more, tables should be reserved for data and tabular information and not for page layout.

In order to have accessible table data it is important that the table is not too complex, uses elements that help identify and describe the headers and other descriptive content, parses successfully and presents to the person with disabilities a similar way to a person without disabilities.

Table captioning and summaries

ll tables benefit from a <caption> which functions like a title and describes the purpose of the table. The caption is located immediately after the <table> element.

Example 2:

<table>

<caption>Local birthdays</caption>

Captions are not strictly required for accessibility, but it is good practice and is of benefit since it is a text description that the screen reader can understand.

Another descriptive is the summary attribute. This functions similar to the text alternative of an image. It is a method of describing in prose the qualities and relationships of information in the table and increases the ability for people to understand complex tables of information.

Example 3:

<table summary=”This table for the Odysseus cruise liner Agamemnon gives details of the meals available (column headings) for each seating area (row headings) during the voyage”>

With a summary for complex or long tables, a screen reader user is informed of the structure of the table and is better prepared to navigate the row headings to find the information they are after before starting to read the table.

Header tags

The table header element is used to label the table cells of the first column and/or first row to semantically separate it from other table cells. Thus a <th> is used the same as a <td> element except that it is mean to be a heading for that row or column.

Using the table header element <th> tells screen readers that the cell contains text that informs the rest of the row or column, depending on location of the <th>. The rest of the data cells should be contained within the table data elements <td>.

Note: Where possible, create tables that present information in a manner that is best understood by reading by rows, rather than columns. As screen reader users will be receiving the information by rows, if they can be arranged in this way it will be easier for them to understand them.

Example 4:

For a menu, the following table is adequate and the caption will explain the content successfully. However, the headings are not directly connected with the content they describe and it will be read as:

"Today's Lunch Menu. Row 1: Entreé, Main, Dessert. Row 2: Caesar Salad, Roast chicken, Pavlova".

A table with the caption "Today's Lunch Menu". Row 1: "Entreé, Main, Dessert". Row 2: "Caesar Salad, Roast chicken, Pavlova".

Example 5:

This table is organised so that the heading is read with the content it describes:

"Today's Menu. Row one: Entrée, Caesar Salad. Row 2: Main, Roast chicken. Row three: Dessert, Pavlova."

A table with the caption "Today’s Menu". Row 1: "Entrée, Caesar Salad". Row 2: "Main, Roast chicken". Row 3: "Dessert, Pavlova".

Presenting the table structure to be read as rows aids accessibility and does not diminish the experience for others.

The scope attribute

Similar to the header attribute above, the scope attribute describes the heading to screen readers when there is information in both columns and row headings.

Example 6:

<table>

  <caption>Dinner television</caption>

  <tr>

     <th scope="col">TV station</th>

     <th scope="col">6PM</th>

     <th scope="col">7PM</th>

  </tr>

  <tr>

     <th scope="row">ABC (local)</th>

     <td>ABC News</td>

     <td>Big brother</td>

  </tr>

  <tr>

     <th scope="row">SBS (local)</th>

     <td>The Australians</td>

     <td>Redfern</td>

  </tr>

  <tr>

     <th scope="row" id="fox">Fox (cable)</th>

     <td>Fox news</td>

     <td>Twilight</td>

  </tr>

</table>

The scope attribute tells the screen reader every thing right of the row header cell is related to that cell and everything under a column header cell is related to that header. The screen reader can then interpret it to the best of its abilities and will read tables in the way the user has configured their assistive technology to do.

Using header and id to describe content

The header attribute for table cells helps users of assistive technologies to navigate large and complex tables and understand the relationship between the cell and its column and row headers. Headers are particularly good for long rows or complex tables, like the one in Example 7 below.

Example 7:

A table showing the evening television guide, including "TV station", "Time" and "Program". Information in row 1, and columns 1 and 2 are table headers.

The markup for this table is:

<table>

  <caption>Evening television</caption>

  <tr>

    <td>&nbsp;</td>

    <th id="station">TV station</th>

    <th id="6PM">6PM</th>

    <th id="7PM">7PM</th>

    <th id="8PM">8PM</th>

  </tr>

  <tr>

    <th rowspan="2" id="local">Local</th>

    <th id="abc">ABC</th>

    <td headers="local abc 6PM">ABC News</td>

    <td headers="local abc 7PM">Big brother</td>

    <td headers="local abc 8PM">Rake</td>

  </tr>

  <tr>

    <th id="sbs">SBS</th>

    <td headers="local sbs 6PM">The Australians</td>

    <td headers="local sbs 7PM">Redfern</td>

    <td headers="local sbs 8PM">Arts program</td>

  </tr>

  <tr>

    <th id="cable">Cable</th>

    <th id="fox">Fox</th>

    <td headers="cable fox 6PM">Fox news</td>

    <td headers="cable fox 7PM">Twilight</td>

    <td headers="cable fox 8PM">Dancing with the Stars</td>

  </tr>

</table>

In this example, the headers refer to the id values of the corresponding <th> cells to communicate the structure of the information. People using assistive technology may be able to hear the header information if their screen reader is capable of it.

Avoiding complex tables

The table in Example 7 above may be a little too complex to understand since some cells have a rowspan across them. Where possible, consider retaining the basic table structure and reformatting the data for a simpler table, as shown in the Example 8 below, which reorganises the content for a more straightforward layout.

Example 8:

A table showing the evening television guide, including "TV station", "Time" and "Program". Information in row 1 and column 1 are table headers.

The markup for this table is cleaner and will present fewer difficulties because it has grouped the content from the first two columns of the table together. There is some repetition but the table is a simpler structure.

Example 9:

<table>

  <caption>Evening television</caption>

  <tr>

    <th id="station">TV station</th>

    <th id="6PM">6PM</th>

    <th id="7PM">7PM</th>

    <th id="8PM">8PM</th>

  </tr>

  <tr>

    <th id="abc">ABC (local)</th>

    <td headers="abc 6PM">ABC News</td>

    <td headers="abc 7PM">Big brother</td>

    <td headers="abc 8PM">Rake</td>

  </tr>

  <tr>

    <th id="sbs">SBS (local)</th>

    <td headers="sbs 6PM">The Australians</td>

    <td headers="sbs 7PM">Redfern</td>

    <td headers="sbs 8PM">Arts program</td>

  </tr>

  <tr>

    <th id="fox">Fox (cable)</th>

    <td headers="fox 6PM">Fox news</td>

    <td headers="fox 7PM">Twilight</td>

    <td headers="fox 8PM">Dancing with the Stars</td>

  </tr>

</table>

Using tables to layout forms

Some developers still use tables to layout forms so that they can place the field labels to the left of the form fields and align them more easily.

Although this may seem like a straightforward solution it does present a few difficulties. Firstly, it creates distance between the label and input and the screen reader will read out the structure of the table layout among the information of the form. It may also fail to adequately retain focus and relationship between the label and input elements.

With the growing number of mobile users, this layout may cause additional problems for people filling out inputs on smaller screens, since those browsers will render the width of tables as coded and not optimally for those users.

Although technically not in breach of accessibility requirements, it is far better to control forms using semantic markup and not table cells and arrange the layout through CSS positioning and layout properties. The following table is followed by the HTML markup.

Example 10:

A contact form in a table with "Name" in row 1, column 1 and a text box in row 1, column 2, and "Email address" in row 2, column 1 and a text box in row 2, column 2. The "Submit" button is in row 3, column 2.

<form action="http://accessiq.org/contactform.php">

  <table>

  <caption>contact form</caption>

  <tr>

  <th><label for="name">Name <span class="required">(required)</span></label></th>

  <td><input type="text" name="name" id="name" /></td>

  </tr>

  <tr>

  <th><label for="email-address">Email address

     <span class="required">(required)</span></label></th>

  <td><input type="text" name="email-address" id="email-address" /></td>

  </tr>

  <tr>

  <th>&nbsp;</th>

  <td><input type="submit" value="Submit" /></td>

  </tr>

  </table>

</form>

Instead, a version without tables will present a far more semantic and well-structured form that will not create problems for users of screen readers.

Example 11:

<form>

     <h2>Contact form</h2>

     <label for="name">Name

     <span class="required">(required)</span></label><br />

     <input type="text" name="name" id="name" /><br />

     <label for="email-address">Email address

     <span class="required">(required)</span></label><br />

     <input type="text" name="email-address" id="email-address" /><br />

     <input type="submit" value="Submit" />

</form>

This will give you cleaner code, better accessibility and allow you to create more responsive and adaptable layouts, since it adheres to the separation between structure and presentation.

Including WAI-ARIA

In addition to the above, it is always good practice to investigate the Accessible Rich Internet Applications (ARIA) properties that may apply to your particular situation. In this case, there are ARIA roles called columnheader and rowheader that can be used as attributes of a <th> element in a table. These supplement any existing semantic value the <th> element supplies, targeting screen readers specifically.

In addition, you can also use the aria-labelledby property to label table cells in a similar way to the method noted in the description of the user of headers above.

Example 12:

<tr>

     <th id="abc">ABC (local)</th>

     <td headers="abc 6PM" aria-labelledby=”abc 6PM”>ABC News</td>

     <td headers="abc 7PM" aria-labelledby=”abc 7PM”>Big brother</td>

     <td headers="abc 8PM" aria-labelledby=”abc 8PM”>Rake</td>

  </tr>

Whenever invoking ARIA attributes, roles or properties it is best to ensure that you test them extensively with common screen readers and your target browsers to reduce the likelihood of the values being repeated due to over-zealous assistive technologies.