Accessible (web app) table: a good table with a bad rep
The table tag <table> has a bad reputation in HTML. This is mainly due to the past. Before CSS took a large role in HTML design, tables were used by many for the markup of the entire web page. Sometimes, this is still the case and that, along with the bad-accessibility-rumor, gives tables a bad rep. When we see a table in HTML, we, immediately and full of prejudice, cringe a bit. Yet, using tables is not always bad practice.
Tables are an essential tool for visualizing data in web apps. A good reason to use a table is for displaying tabular information. An example of a good accessible table would the following:
<table summary="Give a to-the-point summary of the table, but do also give all information that you think will help understand the table better, even if this means a more lengthy summary.">
<caption>Short description of my table.</caption>
<th abbr="Column 1" id="My_column_title_1">My column title 1</th>
<th abbr="Column 2" id="My_column_title_2">My column title 2</th>
<th id="My_row_title_1">My row title 1</th>
<td header="My_column_title_1 My_row_title_1">Data 1 for column 1</td>
<td header="My_column_title_2 My_row_title_1">Data 1 for column 2</td>
<th id="My_row_title_2">My row title 2</th>
<td header="My_column_title_1 My_row_title_2">Data 2 for column 1</td>
<td header="My_column_title_2 My_row_title_2">Data 2 for column 2</td>
And some additional information with that:
- The caption will be displayed above the table and can be easily styled with CSS.
- The summary won't be visible on the web page, but will make the table more accessible for screen readers.
- Use table headers <th> for all data that is used as a header. Screen readers will be able to see the header that belongs to a table cell. When you have really long headers, then you can imagine that this can be very annoying. In that case, use the abbreviation attribute. The screen reader will then read the abbreviated version.
- thead can be nice to have, because you can take the header and easily style it separately. For a small table, though, using th will suffice. thead, tbody and tfoot are not required. For large, multi page tables, especially in web applications, though, the use of thead, tbody and tfoot can provide more structure and meaning to the table. You could easily repeat these sections of the table on multiple pages. Remember that if you use thead or tfoot, you have to use tbody to specify what part of the table is the main body part.
Try to avoid too complex tables, because this will make the data hard to understand for users with assistant devices. Sometimes, though, you don't have a choice. In that case, these are some of the things that you can do to make the experience for those users a bit better:
- Add an id attribute with the headers (<th>). The screen reader won't be able to read the id out, but this way you can associate a particular table cell with a particular header.
- Add a header attribute with all the regular table cells (<td>). This associates the cells with the appropriated headers. In the header attribute, you should put each id of all the headers where this cell falls under, in the proper order and separated by spaces. The screen reader will read it then as "column x row x" and then the values of the header id's in the header attribute, plus the value of the cell itself. For example: "Data 1 for column 1" will be read by the screen reader as: "column 2 row 2 My column title 1 My row title 1 Data 1 for column 1".
- When you have more than 2 levels of headers, then also include the header attribute in the header tag, stating the name of the id('s) of the header(s) where it falls under. Just as you do with the table cells.