Building Accessible Data Tables: Best Practices - Accessmeter Consulting

E-commerce: Accessible Data Tables

We evaluated several e-commerce sites and found that most of them feature data tables. This is likely because data tables effectively organize and present large amounts of information clearly.

Notably, over 80% of these data tables were not properly implemented using accessible coding best practices.

Learn more about accessible data tables and how to address prevalent data table issues, which can potentially resolve up to 90% of the challenges commonly encountered by these platforms.

If you need custom support for your accessibility project, we are experts ready to help.

Get Support

What is a data table?

To keep it simple, A data table is a structured arrangement of data in rows and columns that makes it easier to view, organize, and analyze information.

Broadly speaking, there are two types of tables:

  • Presentation tables: Used purely to arrange page elements visually. These tables are not intended to convey structured data but rather to help with the layout and design of a webpage. They often involve merging cells or adding styles to achieve a desired appearance.
  • Data tables: Used to present data in a logical and organized way. These tables are designed to display structured information, making it easy for users to read, compare, and analyze data.

In the context of e-commerce sites, data tables are often used to display product lists, customer information, order details, stock prices, financial records, and other relevant data in a systematic way. Each row typically represents a different item or entry, while each column represents a different attribute or piece of information about those entries.

Data tables allow users to quickly scan and compare different pieces of data, and they also facilitate various operations like sorting, filtering, and searching within the table.

Proper implementation of data tables includes ensuring accessibility features, such as using appropriate semantic HTML tags (<table>, <tr>, <th>, <td>) and providing descriptive headers and captions, to ensure that the information is accessible to all users, including those using assistive technologies.

Wrongly implemented data tables pose a significant challenge to users with disabilities. This is because assistive technologies may not be able to properly associate each piece of data within the table with its appropriate column and/or row headers.

Types of data tables

In the context of accessibility testing, we recognize three simple types of data tables, which are:

  1. Tables with column headers only: These tables have headers at the top of each column, providing context for the data in that column. Each cell in the table is associated with a column header, but there are no row headers.
  2. Tables with row headers only: These tables have headers at the beginning of each row, giving context for the data in that row. Each cell in the table is associated with a row header, but there are no column headers.
  3. Tables with both column and row headers: These tables have headers for both columns and rows, offering a comprehensive context for each cell by providing relevant information from both dimensions. This type of table is particularly useful for displaying complex data where understanding the relationship between rows and columns is important.

Why creating accessible data tables is important

Creating accessible data tables is important because it ensures that all users, including those with disabilities, can access and understand the information presented. According to the Web Content Accessibility Guideline (WCAG), Success Criterion 1.3.1-Info and Relationships. Information, structure, and relationships conveyed through presentation should be programmatically determinable or available in text.

This implies that:

  • Data tables should allow screen readers and other assistive technologies to correctly interpret and convey the data to users, ensuring that those who rely on these tools can navigate and comprehend the table’s content.
  • Providing accessible data tables promotes equal access to information for everyone, regardless of their abilities. This is essential for inclusivity and non-discrimination.
  • Well-structured, accessible tables enhance usability for all users by making data easier to read, understand, and interact with. This leads to a better user experience overall.

Alright, enough of the background stuff. Let’s dive into passing examples and failing examples for each type of data table.

Tables with column headers only

Failing Example:

Code:
The following code snippet shows a failing data table with only column headers: <table> <caption>Quarterly Sales Data</caption> <tr> <td>1st Quarter</td> <td>2nd Quarter</td> <td>3rd Quarter</td> <td>4th Quarter</td> </tr> <tr> <td>100</td> <td>120</td> <td>80</td> <td>90</td> </tr> <tr> <td>150</td> <td>130</td> <td>95</td> <td>110</td> </tr> <tr> <td>80</td> <td>100</td> <td>70</td> <td>85</td> </tr> <tr> <td>200</td> <td>180</td> <td>150</td> <td>160</td> </tr> <tr> <td>530</td> <td>530</td> <td>395</td> <td>445</td> </tr> </table>
Result:
Quarterly Sales Data
1st Quarter 2nd Quarter 3rd Quarter 4th Quarter
100 120 80 90
150 130 95 110
80 100 70 85
200 180 150 160
530 530 395 445

This table is a failing example because it lacks a <th> element to define the column headers and a <tbody> element to define the table body. Screen readers will struggle to associate the data cells with their appropriate headers, leading to confusion for users relying on assistive technologies.

Passing Example

Code:
The following code snippet shows a passing data table with only column headers: <table> <caption>Quarterly Sales Data</caption> <thead> <tr> <th>1st Quarter</th> <th>2nd Quarter</th> <th>3rd Quarter</th> <th>4th Quarter</th> </tr> </thead> <tbody> <tr> <td>100</td> <td>120</td> <td>80</td> <td>90</td> </tr> <tr> <td>150</td> <td>130</td> <td>95</td> <td>110</td> </tr> <tr> <td>80</td> <td>100</td> <td>70</td> <td>85</td> </tr> <tr> <td>200</td> <td>180</td> <td>150</td> <td>160</td> </tr> <tr> <td>530</td> <td>530</td> <td>395</td> <td>445</td> </tr> </tbody> </table>
Result:

 

Quarterly Sales Data
1st Quarter 2nd Quarter 3rd Quarter 4th Quarter
100 120 80 90
150 130 95 110
80 100 70 85
200 180 150 160
530 530 395 445

This table is a passing example because there is a <thead> element to define the column headers and a <tbody> element to define the table body. Screen readers will properly associate the data cells with their appropriate headers.

Tables with Row headers only

Failing Example:

Code:
The following code snippet shows a data table with only row headers: <table> <caption>Quarterly Sales Data</caption> <tr> <td>1st Quarter</td> </tr> <tr> <td>2nd Quarter</td> </tr> <tr> <td>3rd Quarter</td> </tr> <tr> <td>4th Quarter</td> </tr> <tr> <td>100</td> </tr> <tr> <td>120</td> </tr> <tr> <td>80</td> </tr> <tr> <td>90</td> </tr> <tr> <td>150</td> </tr> <tr> <td>130</td> </tr> <tr> <td>95</td> </tr> <tr> <td>110</td> </tr> <tr> <td>80</td> </tr> <tr> <td>100</td> </tr> <tr> <td>70</td> </tr> <tr> <td>85</td> </tr> <tr> <td>200</td> </tr> <tr> <td>180</td> </tr> <tr> <td>150</td> </tr> <tr> <td>160</td> </tr> <tr> <td>530</td> </tr> <tr> <td>530</td> </tr> <tr> <td>395</td> </tr> <tr> <td>445</td> </tr> </table>
Result:
Quarterly Sales Data
1st Quarter 100 150 80 200 530
2nd Quarter 120 130 100 180 530
3rd Quarter 80 95 70 150 395
4th Quarter 90 110 85 160 445

This table is a failing example because there is no <th> element to define the table headers. Screen readers will not properly associate the data cells with their appropriate row headers.

Passing Example

Code:
The following code snippet shows a data table with only row headers: <table width="548"> <caption>Quarterly Sales Data</caption> <tbody> <tr> <th scope="row">1st Quarter</th> <td>100</td> <td>150</td> <td>80</td> <td>200</td> <td>530</td> </tr> <tr> <th scope="row">2nd Quarter</th> <td>120</td> <td>130</td> <td>100</td> <td>180</td> <td>530</td> </tr> <tr> <th scope="row">3rd Quarter</th> <td>80</td> <td>95</td> <td>70</td> <td>150</td> <td>395</td> </tr> <tr> <th scope="row">4th Quarter</th> <td>90</td> <td>110</td> <td>85</td> <td>160</td> <td>445</td> </tr> </tbody> </table>
Result:

 

Quarterly Sales Data
1st Quarter 100 150 80 200 530
2nd Quarter 120 130 100 180 530
3rd Quarter 80 95 70 150 395
4th Quarter 90 110 85 160 445

This table is a passing example because there is a <th> element to define the row headers and a <tbody> element to define the table body. Screen readers will properly associate the data cells with their appropriate row headers.

Tables with Both Column & Row headers

Failing Example:

Code:
The following code snippet shows a data table with both row and column headers: <table style="height: 238px;" width="548"> <caption>Quarterly Sales Data</caption> <thead> <tr> <th></th> <th>Week 1</th> <th>Week 2</th> <th>Week 3</th> <th>Week 4</th> <th>Week 5</th> </tr> </thead> <tbody> <tr> <td scope="row">1st Quarter</td> <td>100</td> <td>150</td> <td>80</td> <td>200</td> <td>530</td> </tr> <tr> <td scope="row">2nd Quarter</td> <td>120</td> <td>130</td> <td>100</td> <td>180</td> <td>530</td> </tr> <tr> <td scope="row">3rd Quarter</td> <td>80</td> <td>95</td> <td>70</td> <td>150</td> <td>395</td> </tr> <tr> <td scope="row">4th Quarter</td> <td>90</td> <td>110</td> <td>85</td> <td>160</td> <td>445</td> </tr> </tbody> </table>
Result:
Quarterly Sales Data
Week 1 Week 2 Week 3 Week 4 Week 5
1st Quarter 100 150 80 200 530
2nd Quarter 120 130 100 180 530
3rd Quarter 80 95 70 150 395
4th Quarter 90 110 85 160 445

This table is a failing example because it lacks <th> elements to define the row headers. While screen readers will correctly associate each data cell with its column headers, they will not properly associate the data cells with their corresponding row headers.

Passing Example

Code:
The following code snippet shows a data table with both row and column headers: <table style="height: 238px;" width="548"> <caption>Quarterly Sales Data</caption> <thead> <tr> <th></th> <th>Week 1</th> <th>Week 2</th> <th>Week 3</th> <th>Week 4</th> <th>Week 5</th> </tr> </thead> <tbody> <tr> <th scope="row">1st Quarter</th> <td>100</td> <td>150</td> <td>80</td> <td>200</td> <td>530</td> </tr> <tr> <th scope="row">2nd Quarter</th> <td>120</td> <td>130</td> <td>100</td> <td>180</td> <td>530</td> </tr> <tr> <th scope="row">3rd Quarter</th> <td>80</td> <td>95</td> <td>70</td> <td>150</td> <td>395</td> </tr> <tr> <th scope="row">4th Quarter</th> <td>90</td> <td>110</td> <td>85</td> <td>160</td> <td>445</td> </tr> </tbody> </table>
Result:

 

Quarterly Sales Data
Week 1 Week 2 Week 3 Week 4 Week 5
1st Quarter 100 150 80 200 530
2nd Quarter 120 130 100 180 530
3rd Quarter 80 95 70 150 395
4th Quarter 90 110 85 160 445

This table is a passing example because there is a <th> element to define the row and column headers and a <tbody> element to define the table body. Screen readers will properly associate each data cell with its appropriate row and column headers.

Let’s Wrap It Up

The most common errors we often find when testing websites featuring data tables are improper associations of each cell with their corresponding column and row headers. Users with disabilities may find these kinds of tables difficult to comprehend.

Since most charts and graphs used to convey data on e-commerce sites can be made accessible by providing text alternatives in the form of data tables, it becomes very necessary to make these tables accessible.

Start Building Accessible Solutions Today

We are an agency that knows our onions. Let us transform your rigid websites into highly accessible fortresses.

HIRE US