Proper table markup is a must for accessibility. When tables don't provide the proper semantics, assistive tech users can have a hard time understanding the data relationships.
Checklist for tables1
Semantic Markup for Tabular Data
Tabular data SHOULD be represented in a
- Data tables SHOULD have a programmatically-associated caption or name.
- The name/caption of a data table SHOULD describe the identity or purpose of the table accurately, meaningfully, and succinctly.
- The name/caption of each data table SHOULD be unique within the context of other tables on the same page.
- Table headers MUST be designated with
- Data table header text MUST accurately describe the category of the corresponding data cells.
Simple Header Associations
Table data cells MUST be associated with their corresponding header cells.
Grouped Header Associations
Table data group headers MUST be associated with their corresponding data cell groups.
Complex Header Associations
Header/data associations that cannot be designated withand scope MUST be designated with headers plus id.
Nested or Split Tables
Data table headers and data associations MUST NOT be referenced across nested, merged, or separate tables.
- A summary MAY be provided for data tables.
- A data table summary, if provided, SHOULD make the table more understandable to screen reader users.
- Tables SHOULD NOT be used for the purpose of purely visual (non-data) layout.
- Layout tables MUST NOT contain data table markup.
Avoid the following
Things get tricky when we need to build responsive views for tables. Depending on the number of columns the layout might need stack for smaller viewports then go to standard table grid layout for larger viewports.
The following example illustrates:
- Fake table marked up to support only the visual layout
- Lack of relationship between headings and data
- A screen reader user will have to use their arrow key to advance sequentially through elements as they appear in the DOM (markup order), they will hear all the "heading" text before getting to any values
<div class="table"> <div class="table__header add-bold"> <p> Service Date </p> <p> Patient </p> <p> Provider </p> <p> Billed </p> <p> Patient Responsibility </p> </div> <div class="table__content"> <p> 10/23/2018 </p> <p> Patient Name </p> <p> Provider Name </p> <p> $244.00 </p> <p> $188.71 </p> </div> </div>