Accessible Tables (Part 1)

Tables are a great way to format tabular data, and just a little extra markup will make them easier to be understood by assistive devices.

The Table Nightmare

Tables can be an important part of many websites, especially those selling a product or service. Unfortunately, tables can also be an absolute nightmare to navigate using a screen reader. Consider the following table (the data is all made up), which I’ve intentionally left out all table headers and summaries:

Sushi Roll Calories Fat Carbs Protein
California Roll 300 20 42 16
Spicy Tuna Roll 255 17 31 12
Avocado Roll 428 22 16 19

Here is the corresponding markup:


<table>
	<tr>
     		<td>Sushi Roll</td>
     		<td>Calories</td>
     		<td>Fat</td>
     		<td>Carbs</td>
     		<td>Protein</td>
	</tr>
	<tr>
     		<td>California Roll</td>
     		<td>300</td>
     		<td>20</td>
     		<td>42</td>
     		<td>16</td>     
	</tr>
	<tr>
     		<td>Spicy Tuna Roll</td>
     		<td>255</td>
     		<td>17</td>
     		<td>31</td>
     		<td>12</td>     
	</tr>
	<tr>
     		<td>Avocado Roll</td>
     		<td>428</td>
     		<td>22</td>
     		<td>16</td>
     		<td>19</td>     
	</tr>
</table>

Any screen reader would read the table the following way: Sushi Roll, Calories, Fat, Carbs, Protein, California Roll, 300, 20, 42, 16, etc. When read this way, there is no clear association between the nutrition facts and the category they belong to. The user would have to memorize the categories first and on the fly, try to figure out what each number corresponds to, which isn’t very convenient.

The Table Header Solution


<table>
	<thead>
		<tr>
     		        <th id="roll">Sushi Roll</th>
     		        <th id="calories">Calories</th>
     		        <th id="fat">Fat</th>
     		        <th id="carbs">Carbs</th>
     		        <th id="protein">Protein</th>
		</tr>
	</thead>
	
	<tbody>
		<tr>
     		        <td headers="roll">California Roll</td>
     		        <td headers="calories">300</td>
     		        <td headers="fat">20</td>
     		        <td headers="carbs">42</td>
     		        <td headers="protein">16</td>     
		</tr>
		<tr>
     		        <td headers="roll">Spicy Tuna Roll</td>
     		        <td headers="calories">255</td>
     		        <td headers="fat">17</td>
     		        <td headers="carbs">31</td>
     		        <td headers="protein">12</td>     
		</tr>
		<tr>
    		        <td headers="roll">Avocado Roll</td>
    		        <td headers="calories">428</td>
    		        <td headers="fat">22</td>
    		        <td headers="carbs">16</td>
    		        <td headers="protein">19</td>     
		</tr>
        </tbody>
</table>

We haven’t added too much markup here, but we’ve taken the first step towards making our table completely accessible. First, we assigned unique ids to each one of our table headers. Next, we added the headers attribute to each list item and assigned it the value of our corresponding header id.

You’ll may also notice that we added two other unique elements that help define the table structure: thead and tbody. I’ll cover how they’re used, as well as tfoot, captions, and summaries in the next tutorial. So what exactly did we accomplish?

Now when a screen reader enters a table and starts reading the data, it will read the table header before each item in the table. Our table would be read back like this: Sushi Roll, California Roll, Calories, 300, Fat, 20, Carbs, 42, Protein, 16.

Bellissimo!

By Kyle Petersen | 9 months, 1 week, 5 days, 1 hour, 3 minutes ago

Commenting is not available in this weblog entry.